Rhyme/Java 多态的深入理解—多态的详细分析以及多态应用之钩子函数的详细解释

Java多态的深入理解

1、Java面向对象的三大特性:继承、封装、多态

2、多态产生的条件:继承、方法重写、父类引用指向子类对象

例如以下程序:

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

通过以上程序我们可以了解到多态带给我们的好处,那就是可扩展性很强,想想看如果我还有其他的动物子类,那么我只要再写一个子类继承Animal类即可,而无须修改其他任何代码;
如果和我们现实世界中的待人处事联系起来,多态的道理就是说一套,做一套,说的时候不把话说死,那么真正做的做的时候就会有多种选择。

然年再来回顾一下我们说的产生多态的三个条件:继承、子类重写父类方法、父类对象指向子类对象。

继承:

这里写图片描述

子类重写父类方法:

因为你会发现如果你的子类不重写父类的方法,那么多态就变得没有意义了

这里写图片描述

这里写图片描述

父类引用指向子类对象

这里写图片描述

3、多态的内存分析

我们还是以上的代码为例

这里写图片描述

首先我们知道会先进行类加载操作,同时在方法区中创建Cat对象,但是在创建Cat对象先创建它的父类,因此就产生了图中的对象;另外需要注意的是,不管是Object、Animal还是Cat方法中的隐式参数this指向的都是Cat对象的地址

4、对象的强制转化问题

你会发现以下的问题:

这里写图片描述

首先我们通过以上的内存可以清楚的看到cat对象指向的内存地址就是实实在在Cat对象,按理来说,应该能够调用Cat对象中的catchMouse()方法,但是确调不了,这是为什么呢?

原因在与我们的编译器不够智能,它只认写在变量名之前的类型,cat前的类型是Animal,那么编译器就会认为cat就是Animal对象,然后发现Animal对象中并没有catchMouse()方法,便会出现以上的编译错误。

那么我们如何解决呢?答案就是强制类型转化

这里写图片描述

如果你仔细观察的话,你会发现我在强制转型之前使用 instanceof 进行了类型检查,原因在于,编译器不会管你强转是否合理,也就是即使你写出以下不合理的代码,编译器也是不会报错的。所以强烈建议,在进行类型转化之前切记使用instanceof 进行类型检查

这里写图片描述

5、多态应用之钩子函数的解释

我们以Java Web中常用的Servelet中的钩子函数为例

这里写图片描述

这里写图片描述

上面的代码,我们发现在父类中的service()方法调用了doGet()方法,并且在子类MyServlet中对doGet()方法进行了重写,那么请问我们调用方法service()时,里面会执行子类还是父类的doGet()方法?

这里写图片描述

以上出现的情景就叫钩子函数,就是你只是重写了父类的某个方法,但是这个重写方法却生效了

那么,到底发生了什么,我们通过内存来进行分析一番

这里写图片描述

请仔细观看我在图中圈了两层的内容,对没错原因就在于隐式参数this自始至终指向的都是Cat对象,HttpServlet类中的方法也是如此,所以你创建出的对象my,在调用父类的方法service()时,由于service方法中的隐式参数this指向的是Cat对象,就相当于在service()方法中调用的是this.doGet()方法,所以调用的是子类重写的方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值