属性看编译类型,(能调用的)方法看运行类型
就是说你可以用哪些成员是由编译类型决定的,但在调用方法时会基于你创建的对象空间进行层级查找调用
(重点看最后一行代码)上面的例子就好像有种骗过编译器的感觉?对的,如果子类中没有override函数,那么最后一行是会报错的哦;现在有override,就好像编译器以为你写下这段代码会跑父类中的这个方法,可是你和jvm串通好啦,我们要运行子类里重写的方法
我们这里变式一下:
始终牢记:调用方法时看的是运行类型(看究竟哪个对象空间嘛)
下面这个子类中也有geti()所以会优先执行它,而sum()没有被重写,只能老老实实执行父类的
class Father {
public int i = 10;
public int sum() {
return geti() + 10;
}
public int geti() {
return i;
}
}
class Son extends Father {
public int i = 18;
public int geti() {
return i;
}
}
class Main {
public static void main(String[] args) {
Father test = new Son();
System.out.println(test.sum()); // 28
}
}