Java多态----父类引用指向子类对象

多态: 一定是发生在 子父类/接口和实现类 之间。

首先,Java多态有三个必要条件:
1、 继承
2、 子类重写父类方法
3、 父类引用指向子类对象

然后看一个例子:

java项目中子项目如何引用父项目的依赖 java父类引用指向子类_父类

java项目中子项目如何引用父项目的依赖 java父类引用指向子类_子类_02


输出结果为:

java项目中子项目如何引用父项目的依赖 java父类引用指向子类_java_03


给出结论:

Father  c  =  new  Child()    在c的眼里只能看到 child 里面的 father 属性!
 当满Java多态的三个条件时,可以发现c.eat()调用的实际上是子类的eat(是因为子类重写覆盖了父类方法),但c.age调用的还是父类的age(**属性/变量不存在重写和覆盖**),而c.play()则不会通过编译。

java项目中子项目如何引用父项目的依赖 java父类引用指向子类_多态_04


java项目中子项目如何引用父项目的依赖 java父类引用指向子类_子类_05

但是在java的引用中Father不但指定了c以何种方式访问内存,也规定了能够访问内存空间的大小。
我们看Father实例对象的大小是占两行,但Child实例对象占三行(这里就是简单量化一下)。
所以虽然c指向的是Child实例对象,但是前面有Father修饰它,它也只能访问两行的数据,也就是说c根本访问不到Child类中的age!!!只能访问到Father类的age,所以输出40。

java项目中子项目如何引用父项目的依赖 java父类引用指向子类_java_06

我们看到Parent的方法表占三行,Child的方法表占4行,c虽然指向了Child类的实例对象,
	而对象中也有指针指向Child类的方法表,但是由于c受到了Father的修饰,通过c也只能访问到Child方法表中前3行的内容!!!!
	然而前面说过,在方法表的形成过程中,子类重写的方法会覆盖掉表中原来的数据,也就是Child类的方法表的第三行是指向Child.eat的引用,
	而不是指向Parent.eat(因为方法表产生了覆盖),所以c访问到的是Child.eat。也就是子类的方法!!!这种情况下,c是没有办法直接访问到父类的eat方法的。