一行代码突然挡住了菜鸟前进的道路:father f=new son();
貌似牛头不搭马嘴的样子,自己一下子都懵了,不同数据类型的值还能互相赋值的吗,以前的学基本数据类型里提到过数据类型的转换,记得几行很经典的代码(不过是反面教材):
short sh=5;
sh=sh-3;
敲进“伊柯丽不是”里一运行,它就嗡嗡的又哭又闹的提示说“类型转换有误”。苦思闷想一早上,终于有点明白了,原来sh-3已经是int数据类型的值了,赋值给一个shor类型的sh当然不愿意了。
于是再鼓捣一下,换个马脸:
sh-=3;
再扔进“伊柯丽不是”里运行,它不闹,说明这是可以,这会轮到我哭闹了。为什么这样就没错呢?拽着咱们班的“大神”蹲在“伊柯丽不是”前叫他来一下子,他也头晕。这下可好,把大神难倒,只有寻找民间偏方,去问那些平时不学习但期末考试成暴发户的同学,最终得到一个结论:sh-=3里已经包含强制类型转换。恩···装着接受这个解释
而现在又出新难题。为什么可以子类的实例赋值给父类的对象?这是那个门派的阴招呢?为什么要这样耍出来呢?有什么好处?
都“度娘”里折腾了一番,得到一条重要的消息:
1)子类里有一个区域放的父类的实例,子类内存区里有一个this指针,指向了这个内存区里包括的父类实例区,当把引用付给父类时,是把子类内存区里面的父类实例区域的引用给了父类的实例.
2)super相当于指向父类示例的一个指针; 子类只保存子类的信息和super指针; 当JVM加载一个子类的时候也会把它的父类一同加载的,子类内部通过super保存父类的一个引用
也就是说在son类的内存区里,有一个区域放着father类的实例。取名为super;super里保存着指向father类的地址(这也是为什么在子类中可以用super()来代替父类的原因)。
因此真相大白了,father f=new son();当son类继承了father类之后,它已经保存了指向father类的地址信息,此时即是用父类引用指向子类对象 ,这是一种向上转型,当父类需要使用子类功能时(父类被子类覆盖的方法)就可以将子类对象上转给父类引用。
不仅仅是父类可以指向子类的对象,只要是祖先类都可以指向子类的实例。典型情况,Object是所有类的祖先类,所以Object类型的对象引用可以指向任何对象。例如下面的代码:
Object o = new son();
那么把父类引用指向子类对象的好处是什么呢?
其实,父类引用指向子类对象就是java的多态。也叫动态绑定。
把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化。 赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。也就是说,父亲的行为像儿子,而不是儿子的行为像父亲