我们来看上面part1部分:
cat cat_ = new cat(); cat_.eat(); cat_.sleep(); cat_.work();结果:
吃鱼猫会睡懒觉。动物可以帮助人类干活!cat_.work(); 这处继承了父类animal的方法,还是很好理解的
我们接着看part2:
animal cat=new cat(); cat.eat(); cat.work(); cat.sleep();//此处编译会报错。 animal dog=new dog(); dog.eat();//结果为:吃骨头。此处调用子类的同名方法。这块就比较特殊了,我们一句句来看
animal cat=new cat(); 像这种这个 父类引用指向子类对象,这种现象叫做: 向上转型 ,也被称为 多态的引用 。
cat.sleep();这句 编译器会提示 编译报错。表明:当我们当子类的对象作为父类的引用使用时,只能访问子类中和父类中都有的方法,而无法去访问子类中特有的方法
值得注意的是:向上转型是安全的。但是缺点是:一旦向上转型,子类会丢失的子类的扩展方法,其实就是 子类中原本特有的方法就不能再被调用了。所以cat.sleep()这句会编译报错。
cat.eat();这句的结果打印:吃鱼。程序这块调用我们cat定义的方法。
cat.work();这句的结果打印:动物可以帮助人类干活!我们上面cat类没有定义work方法,但是却使用了父类的方法,这是不是很神奇。其实此处调的是父类的同名方法
animal dog=new dog();dog.eat();这句的结果打印为:吃骨头。此处调用子类的同名方法。
由此我们可以知道当发生向上转型,去调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。如果子类没有同名方法,会再次去调父类中的该方法
向上转型
我们现在知道了 向上转型时会丢失子类的扩展方法,哎,但我们就是想找回来,这可咋办?
向下转型可以帮助我们,找回曾经失去的
我们来看part3:
cat cat_real = (cat)cat; //注意 此处的cat 对应上面父类animal,可不是子类 cat_real.sleep();cat cat = (cat)cat; cat222.sleep(); 这个向下转型非常像强转。
打印的结果:猫会睡懒觉。此处又能调用了 子类cat 的 sleep()方法了。
一道简单的面试题我们再来看一道有意思的题,来强化理解
public class main { static class animal{ int weight = 10; public void print() { system.out.println(this animal print: + weight); } public animal() { print(); } } static class dog extends animal { int weight = 20; @override public void print() { system.out.println(this dog print: + weight); } public dog() { print(); } } public static void main(string[] args) { dog dog = new dog(); system.out.println(---------------); animal dog222 = new dog(); dog dog333 = (dog)dog222; system.out.println(---------------); dog dog444 = (dog)new animal(); }}执行结果:
this dog print:0this dog print:20---------------this dog print:0this dog print:20---------------this animal print:10exception in thread main java.lang.classcastexception: com.zj.main$animal cannot be cast to com.zj.main$dog at com.zj.main.main(main.java:15)做对了嘛,不对的话,复制代码去idea中debug看看
我们先看第一部分
dog dog = new dog();
程序内部的执行顺序:
先 初始化 父类animal 的属性 int weight=10然后 调用父类animal的构造方法,执行print()实际调用子类dog的print()方法,打印:this dog print:0,由于此时的子类属性weight 并未初始化初始化 子类dog 的属性 int weight=20调用 子类dog的构造方法,执行print()实际调用当前类的print()方法,打印this dog print:20其中有几处我们需要注意一下:实例化子类dog,程序会去默认优先实例化父类,即子类实例化时会隐式传递dog的this调用父类构造器进行初始化工作,这个和jvm的双亲委派机制有关,这里就不展开讲了,先挖个坑,以后再来填
苹果Apple TV+捆绑购买拉低iPhone利润率
后发而先至的腾讯混元大模型,到底有哪些技术亮点?
GTC23 | NVIDIA 为全球企业带来生成式 AI,推出用于创建大型语言模型和视觉模型的云服务
焕发年轻健康肌肤,宙斯美容仪遇挑战
人脸识别国家标准发布,海康、大华、商汤、小米等参与制定
全面讲解⾯向对象编程三⼤特性 2
Senodia深迪六轴陀螺仪方案应用
华为云OBS,助力企业海量、安全、高可靠、低成本数据存储
为什么可以说vivo和oppo再火 也永远比不上华为!
中芯国际揭露产能满载、芯片缺货的2大因素
华为云弹性公网IP服务,实惠又便捷!
微硕SGT工艺场效应管新品上线,关于SGT MOSFET你了解多少?
首批国产Model 3交付 有望撼动中高端电动车市场格局
黄曲霉毒素定量检测仪的特点
三菱电机电动汽车电力调节器的关键特征
砥砺前行、不忘初心——鼎阳科技亮相第五十届全国高教仪器展示会
Oculus旨在利用虚拟现实技术培训专业医疗人员
步进电机驱动电路解析,步进电机驱动电路原理图、电路性能比较及电路实例
微雪电子ZIGBEE开发板 CC2530 Eval Kit简介
传闻德州仪器欲出164亿美元收购AMD,行业分析师:不靠谱