对象调用编译时类型的属性和运行时类型的方法
编译时,JVM会在栈中静态创建基本数据变量,和引用数据变量的引用
根据继承的特点我们可以知道,子类会继承父类非私有的属性和方法,也就是说,父类的(非私有)属性也会出现在子类中,当然,这是显而易见的,然而关键在于,如果子类重新定义了这一属性,会怎么样呢?实际上,父类的属性并不会被覆盖,为了方便起见,我把从父类继承来的属性记为– 属性<父类> 而自己重新定义的同名属性为–属性<子类> 这样,在子类中,会有两个属性 即:属性<父类> 属性<子类>,那么如何调用呢?–解答:<>中的内容对应着调用该属性的对象的编译时类型,编译时类型为父类,调用属性<父类> ,另一种情况就是调用子类的属性了。
Class A中定义属性a,Class B继承自A,重新定义了属性a,此时,B中有编译时类型为A的属性a和编译时类型为B的属性a,Class C继承自B,自己重新定义了属性a,这时,C具有三种编译时类型的属性a。这样就好看多了,不知道应该调用的属性是哪个类的,就只要分析自己的编译时类型就可以了
对于对象调用运行时类型的方法便是出于对多态的考虑了。
class A{
int i=1;
void say(){
System.out.println(i);
}
}
class B extends A{
int i=2;
void say(){
System.out.println(i);
}
}
public class Main{
public static void main(String args[]) {
A a=new B();
System.out.println(a.i); //编译-- 父类
a.say(); //运行-- 子类
}
}