Java的多态为何可以由子类实例化父类
从JVM角度看Java多态 - 青儿哥哥 - 博客园首先,明确一下,Java多态的三个必要条件:
1、 继承
2、 子类重写父类方法
3、 父类引用指向子类对象
然后看一个例子package test.xing;class Father{ protected int age; public Father(){ age = 40; } void eat(){ System.out.println("父亲在吃饭"); }}class Child extends Father{ protected int age; public Child(){ age = 18; } void eat(){ System.out.println("孩子在吃饭"); } void play(){ System.out.println("孩子在打CS"); }}public class TestPolymorphic { public static void main(String args) { Father c = new Child(); c.eat(); //c.play(); System.out.println("年龄:"+c.age ); }}
输出结果为:
给出结论:当满Java多态的三个条件时,可以发现c.eat()调用的实际上是子类的eat,但c.age调用的还是父类的age,而c.play()则不会通过编译。
下面从JVM的角度解释上面这种现象
我们就从Father c = new Child()这句话切入
这句话首先会执行new Child(),在堆中分配一个对象。
当然在分配Child类的实例时,先要通过JVM的类加载器将Child类对应的class文件加载到JVM中,然后JVM根据class文件中的字节流产生一个表示class文件中类型信息的结构体
这个结构体的具体实现,不同的JVM会有不同的实现方式,但大致上都差不多,都要遵守JVM的规范。
这个表示class文件中类型信息的结构体大概由以下几部分构成:
1、 常量池
2、 类变量(静态变量)
3、 字段信息
4、 方法信息
5、 类的父类信息
6、 类的访问权限信息等
这些我说的也不够准确,具体的大家可以看JVM相关的书籍如《深入理解Java虚拟机》,在这里就有个大概的概念就好。
之后,JVM会根据上面这个结构体生成一个叫做方法表的东西。这个方法表是实现java多态的一个关键。
方法表中包含的是实例方法(就是相对于静态方法而言的,用对象访问的那些方法)的直接引用,也就是说通过这个方法表就能够访问到该类的实例方法,
而且,这些实例方法不仅包括本类的方法,还包括其父类的实例方法,以及父类的父类的实例方法(就是一直到Object)。
而且,这些方法中不包含私有方法(因为私有方法不能继承)
方法表中的这些直接应用会指向到JVM中表示类型信息的那个结构体(就是上面那个结构体)的相应的方法信息(就是上面结构体中4的某个位置),当然这只是本类的方法,表中还有父类的方法,相应地指向父类类型信息结构体的具体位置。
可能表达的不够清晰,下面画个图表示。
上面提到过,方法表中不仅包括本类的方法,还包括父类的方法,方法表值这样产生的,以Child类的方法表为例:
首先方法表中,会产生指向继承自Object类的方法的引用,这些包括指向toString的和指向equals的,当然Object中还包括很多方法,这里就不写了
然后方法表中产生指向继承自Parent类的方法的引用,这包括eat,
最后产生指向本类的方法的引用。
这里需要注意的一点是,当Child类的方法表产生指向Parent类中的方法的引用时,会有一个指向eat方法的引用,最后产生指向本类的方法的引用时,也有一个指向eat的引用,这时候,新的数据会覆盖原有的数据,也就是说原来指向Parent.eat的那个引用会被替换成指向Child.eat的引用(占据原来表中的位置)。所以我们看到在Child类的方法表中指向的是Child.eat而Parent类的方法表中指向的是Parent.eat。子类的方法表中就没有指向Parent.eat的引用了。
推荐阅读
- #补贴#江阴为何迟迟没执行?|解忧帮 无锡:机动车报废有补贴
- OC为何跌出语言榜前十
- 何能|布局素质教育 教育巨头为何能迅速推进?
- dart这编程语言现在发展怎么样了,语法与Java,c#很相似,甚至更简洁
- 汽车|把车越卖越贵,全新领克01为何可以这样?
- 阿里程序员网上招人的情况为何如此多见
- 心流西春|为何你的后半箱油总是不耐用?油是正经油,问题可能出在这里
- 一粒尘埃的尘|为何很多新车不再设计“雾灯”,雾灯不重要吗?
- 环球车讯网|宝马MINI 为何在“迷你”的路上越跑越远?
- 汽车一起看|为何说国产高端SUV三强之首是名爵HS,领克和WEY竟无法反驳?