多态的情况下,子父类存在同名的成员变量时,默认访问的是父类的成员变量数据.
2.多态的情况下,子父类存在同名的非静态函数的时候,默认是调用子类的成员函数.
3.多态的情况下,子父类存在同名的静态函数时,默认是调用父类的成员函数.
.
5 个解决方案
#1
这其实就是java多态的实现,首先说成员变量,因为在java中,一个对象实例是存储在堆中的,而这个对象包含的内容有对象头,对象体以及对其字节,首先对象头存放的是对象运行时的数据,像是hashcode,锁标识,类型指针,那么对象体中存放的是对象的成员变量,成员变量包括从父类继承过的成员变量和本类的成员变量,那么如果父类和子类有重名的变量,那么这个时候就要看对象的静态类型是什么了,静态类型就是声明类型,如果声明类型是父类那么就直接选取父类的成员变量,如果声明类型是自己的类那么就选取本身类的成员变量,所以选取同名的成员变量的时候是根据静态类型来的。下面再看下成员方法的选取,方法其实是在方法区存放着一张虚表,虚表中存放着是方法的实际入口地址,在实际对象调用的时候虚表会做动态的改变,如果一个方法在子类中被重写了,而这时静态类型又是父类,那么就把虚表中被重写方法的实际入口地址,替换成被重写的方法的入口地址,所以在调用的时候是访问不到被重写的旧方法的。而静态方法直接就不能被重写,更别说调用被重写之后的方法,而且静态方法是属于类的,所以在调用的时候,直接调用的是本类的方法,与运行时对象是没关系的,希望我讲清楚了,也希望对你有帮助谢谢!
#2
,静态类型就是声明类型,如果声明类型是父类那么就直接选取父类的成员变量,如果声明类型是自己的类那么就选取本身类的成员变量[这话听 得不懂.]比如说
abstract class Animal
{
String name;
static String color="动物颜色";
public Animal(String name){
this.name=name;
}
public static void sleep(){
System.out.println("动物在睡觉");
}
public abstract void run();
}
class Mouse extends Animal
{
static String color="老鼠颜色";
public Mouse(String name){
super(name);
}
public static void sleep(){
System.out.println("老鼠在睡觉");
}
public void run(){
System.out.println(name+"四条腿走路");
}
public void dig(){
System.out.println(name+"老鼠在挖洞");
}
}
子类那个public static void sleep()的静态类型什么是什么?
abstract class Animal
{
String name;
static String color="动物颜色";
public Animal(String name){
this.name=name;
}
public static void sleep(){
System.out.println("动物在睡觉");
}
public abstract void run();
}
class Mouse extends Animal
{
static String color="老鼠颜色";
public Mouse(String name){
super(name);
}
public static void sleep(){
System.out.println("老鼠在睡觉");
}
public void run(){
System.out.println(name+"四条腿走路");
}
public void dig(){
System.out.println(name+"老鼠在挖洞");
}
}
子类那个public static void sleep()的静态类型什么是什么?
#3
多态就记住几个关键点吧:
编译时期,向上转型;
方法调用时,动态绑定;
由于静态字段和方法是随着类加载的,也就是静态加载,要早于对象。所以多态不成立
编译时期,向上转型;
方法调用时,动态绑定;
由于静态字段和方法是随着类加载的,也就是静态加载,要早于对象。所以多态不成立
#4
差不多是这么个意思,专业名次啥的不熟,你看着理解吧:
1.成员变量的由声明决定 A a = new B();都有属性x,x的值由声明的类型A决定
2.非静态函数由实例决定 A a = new B();都有方法test(),test的执行结果由真实实例B决定
3.静态方法属于类 不属于实例 静态方法调用属于class就是这么个意思
#5
我去 比我们老师讲的还详细 受教了!
#1
这其实就是java多态的实现,首先说成员变量,因为在java中,一个对象实例是存储在堆中的,而这个对象包含的内容有对象头,对象体以及对其字节,首先对象头存放的是对象运行时的数据,像是hashcode,锁标识,类型指针,那么对象体中存放的是对象的成员变量,成员变量包括从父类继承过的成员变量和本类的成员变量,那么如果父类和子类有重名的变量,那么这个时候就要看对象的静态类型是什么了,静态类型就是声明类型,如果声明类型是父类那么就直接选取父类的成员变量,如果声明类型是自己的类那么就选取本身类的成员变量,所以选取同名的成员变量的时候是根据静态类型来的。下面再看下成员方法的选取,方法其实是在方法区存放着一张虚表,虚表中存放着是方法的实际入口地址,在实际对象调用的时候虚表会做动态的改变,如果一个方法在子类中被重写了,而这时静态类型又是父类,那么就把虚表中被重写方法的实际入口地址,替换成被重写的方法的入口地址,所以在调用的时候是访问不到被重写的旧方法的。而静态方法直接就不能被重写,更别说调用被重写之后的方法,而且静态方法是属于类的,所以在调用的时候,直接调用的是本类的方法,与运行时对象是没关系的,希望我讲清楚了,也希望对你有帮助谢谢!
#2
,静态类型就是声明类型,如果声明类型是父类那么就直接选取父类的成员变量,如果声明类型是自己的类那么就选取本身类的成员变量[这话听 得不懂.]比如说
abstract class Animal
{
String name;
static String color="动物颜色";
public Animal(String name){
this.name=name;
}
public static void sleep(){
System.out.println("动物在睡觉");
}
public abstract void run();
}
class Mouse extends Animal
{
static String color="老鼠颜色";
public Mouse(String name){
super(name);
}
public static void sleep(){
System.out.println("老鼠在睡觉");
}
public void run(){
System.out.println(name+"四条腿走路");
}
public void dig(){
System.out.println(name+"老鼠在挖洞");
}
}
子类那个public static void sleep()的静态类型什么是什么?
abstract class Animal
{
String name;
static String color="动物颜色";
public Animal(String name){
this.name=name;
}
public static void sleep(){
System.out.println("动物在睡觉");
}
public abstract void run();
}
class Mouse extends Animal
{
static String color="老鼠颜色";
public Mouse(String name){
super(name);
}
public static void sleep(){
System.out.println("老鼠在睡觉");
}
public void run(){
System.out.println(name+"四条腿走路");
}
public void dig(){
System.out.println(name+"老鼠在挖洞");
}
}
子类那个public static void sleep()的静态类型什么是什么?
#3
多态就记住几个关键点吧:
编译时期,向上转型;
方法调用时,动态绑定;
由于静态字段和方法是随着类加载的,也就是静态加载,要早于对象。所以多态不成立
编译时期,向上转型;
方法调用时,动态绑定;
由于静态字段和方法是随着类加载的,也就是静态加载,要早于对象。所以多态不成立
#4
差不多是这么个意思,专业名次啥的不熟,你看着理解吧:
1.成员变量的由声明决定 A a = new B();都有属性x,x的值由声明的类型A决定
2.非静态函数由实例决定 A a = new B();都有方法test(),test的执行结果由真实实例B决定
3.静态方法属于类 不属于实例 静态方法调用属于class就是这么个意思
#5
我去 比我们老师讲的还详细 受教了!