- 当调用对象方法的时候,该方法会和该对象的运行类型绑定
- 当调用对象属性时,没有动态绑定机制,哪里声明,哪里使用,即只看编译类型
代码分析
情况1
定义一个父类A:
public class A {
public int i=10;
public int getI() {
return i;
}
public int sum(){
return getI()+10;
}
public int sum1(){
return i+10;
}
}
定义一个子类B:
class B extends A{
public int i=20;
@Override
public int getI() {
return i;
}
public int sum(){
return i+20;
}
public int sum1(){
return i+10;
}
}
主方法:
A a = new B();
System.out.println(a.sum());
System.out.println(a.sum1());
此时输出结果是什么?
- a对象调用方法时看的是运行类型,a的运行类型是B类,所以调用B类中 的sum()方法,此时运行B类的sum方法时,里面的属性i
是没有动态绑定机制的,所以哪里声明就在哪里使用,此时是运行在B类,所以此时的i就是B类的i 调用sum1方法类似
情况2
public class A {
public int i=10;
public int getI() {
return i;
}
public int sum(){
return getI()+10;
}
public int sum1(){
return i+10;
}
}
A类不变,将B类的sum方法注销,主方法不变,输出会是什么?
class B extends A{
public int i=20;
@Override
public int getI() {
return i;
}
// public int sum(){
// return i+20;
// }
public int sum1(){
return i+10;
}
}
A a = new B();
System.out.println(a.sum());
System.out.println(a.sum1());
- 和之前一样,a的运行类型是B类,但是B类没有这个方法了,这时候就会发挥继承的特性,去父类A类中寻找sum方法,A类的sum方法中又有getI这个方法,继承,顾名思义就是我子类也有你这个方法了,并且B类中也重写了getI这个方法,所以运行getI时又回到B类了,返回的i也是B的属性
情况3
A类不变,把B类中的sum1方法也注销,主方法不变,输出会是多少?
public class A {
public int i=10;
public int getI() {
return i;
}
public int sum(){
return getI()+10;
}
public int sum1(){
return i+10;
}
}
class B extends A{
public int i=20;
@Override
public int getI() {
return i;
}
// public int sum(){
// return i+20;
// }
// public int sum1(){
// return i+10;
// }
}
A a = new B();
System.out.println(a.sum());
System.out.println(a.sum1());
- 刚才分析过a.sum()输出的结果是30,这里就分析a.sum1()会输出什么。同样的,调用sum1方法时会找到父类中去,父类的sum1方法中有直接使用属性i,请注意,属性是没有动态绑定机制的,也就是说当执行sum1方法时,属性i的值就是A类的i,也就是在哪声明在哪使用
补充
假如A是父类,B是子类,声明一个A类对象a时,它是不可以调用B类中的特有方法的
就是 a. 是 点不出来B类中的特有方法的,因为这个时候还没有运行,是在编译阶段,要看编译类型 a的编译类型是A