想知道这个obj 对象 是FU的还是ZI的? 为了更好的理解
1.父类代码
public class Fu{
int num = 10;
public void method(){
System.out.println("父类方法")
}
}
2.子类代码
public class Zi extends Fu{
int num = 20;
ublic void method(){
System.out.println("子类方法");
}
接下来是主方法类界面
public class Demo{
public static void main(String[] args){
Fu obj = new Zi();
obj.method(); //结果是子类里的方法
System.out.println(obj.num); //结果是父类里面的10
}
}
Fu obj = new Zi();
所以是Zi的,看new不看前面。
obj 是由两种类型的,一种是静态类型(又称之为外观类型 Apparent Type),一种是实际类型,对于Obj 来说,静态类型就是FU,实际类型就是ZI。
直白的说,对于引用变量等操作,这种编译器就可以确定的,我们称之为静态分派,他使用的是静态类型,也就是Fu,也就是在编译的时候发现你引用的Fu obj,然后他就不管你实际类型是什么,直接引用到Fu.num 了
但是对于调用obj的method方法,这个执行引用仅仅是引用方法名,需要在运行的时候根据方法描述符(就是 方法返回值啊,方法参数啊方法名啊找到这个方法,子类有就访问子类的,子类没有就尝试访问父类,父类都没有,则报错)也就是说具体的方法还是根据运行的时候 obj实际指向来确认的,这中需要在运行期间才能确定的方式,我们称之为动态分派,由于其实际类型是Zi,自然也就调用的是子类的方法。**这种方式的具体细节可以参考下面连接的第四节 虚拟机动态分派的实现**
更对关于静态分派和动态分配的知识欢迎访问我的博客文章 https://www.zhoutao123.com/page/book/jvm/category/byld2m
其实在运行时还是去找的父类里面的方法,子类继承了父类,可以引用子类实例,子类的method相当于名字一样只是重写了父类的method,输出的就是你重写后的代码,
如果你父类没有method。你可以删除父类方法测试,看他还能不找到,
这样写的话违背了里氏替换原则,当子类重写父类得方法时,在频繁得多态面前,整个继承体系复用性比较差,使用一个基类使类与类之间得关系分开