什么是java的多态

什么是java的多态多态分为两种a.编译时多态:方法的重载;b. 运行时多态:JAVA运行时系统根据调用该方法的实例的类型来决定选择调用哪个方法则被称为运行时多态。(我们平时说得多的事运行时多态,所以多态主要也是指运行时多态);上述描述认为重载也是多态的一种表现,不过多态主要指运行时多态。2.运行时多态a.面向对象的三大特性:封装、继承、多态。从一定角度来看,封装和继承几乎都是为多态而准备的。…

大家好,又见面了,我是你们的朋友全栈君。

多态分为两种

a. 编译时多态:方法的重载;

b. 运行时多态:JAVA运行时系统根据调用该方法的实例的类型来决定选择调用哪个方法则被称为运行时多态。(我们平时说得多的事运行时多态,所以多态主要也是指运行时多态);

上述描述认为重载也是多态的一种表现,不过多态主要指运行时多态。

2.运行时多态

a. 面向对象的三大特性:封装、继承、多态。从一定角度来看,封装和继承几乎都是为多态而准备的。这是我们最后一个概念,也是最重要的知识点。

b. 多态的定义:指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用)

c. 实现多态的技术称为:动态绑定(dynamic binding),是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。

d. 多态的作用:消除类型之间的耦合关系。

e. 现实中,关于多态的例子不胜枚举。比方说按下 F1 键这个动作,如果当前在 Flash 界面下弹出的就是 AS 3 的帮助文档;如果当前在 Word 下弹出的就是 Word 帮助;在 Windows 下弹出的就是 Windows 帮助和支持。同一个事件发生在不同的对象上会产生不同的结果。

下面是多态存在的三个必要条件,要求大家做梦时都能背出来!

多态存在的三个必要条件
一、要有继承;
二、要有重写;
三、父类引用指向子类对象。

 多态的好处

1.可替换性(substitutability)。多态对已存在代码具有可替换性。例如,多态对圆Circle类工作,对其他任何圆形几何体,如圆环,也同样工作。
2.可扩充性(extensibility)。多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。实际上新加子类更容易获得多态功能。例如,在实现了圆锥、半圆锥以及半球体的多态基础上,很容易增添球体类的多态性。
3.接口性(interface-ability)。多态是超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。如图8.3 所示。图中超类Shape规定了两个实现多态的接口方法,computeArea()以及computeVolume()。子类,如Circle和Sphere为了实现多态,完善或者覆盖这两个接口方法。
4.灵活性(flexibility)。它在应用中体现了灵活多样的操作,提高了使用效率。
5.简化性(simplicity)。多态简化对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要。

3.代码理解

看了上面的描述,我们大概知道以下几点:

a. 运行时多态是在父类引用指向子类对象时产生的。一个父类的引用可以指向多种子类对象,那么运行时对于同一个消息应该如何做出响应呢?这就由实际的被引用的对象的类型来决定。

b. 为什么要有重写呢?难道父类中的方法没有被重写,直接调用子类中存在的方法难道是不行吗?看个例子如下:

什么是java的多态

上面的例子中,当父类中的getName()被注释掉以后,调用father.getName()方法会出错。因此,当父类引用指向子类方法时,必须调用那些父类中存在的方法,如果子类中对该方法进行了重写,那么在运行时就会动态调用子类中的方法,这就是多态。

c. 要有继承很好理解,没有继承的话,哪来的重写呢。

4.深一点

基本了解了多态以后,我们就可以看明白下面这个例子了,它的输出结果是什么呢?

什么是java的多态

答案是”son”,结合前面的解释,我们很容易判断出来。子类的getName()方法重写了父类中的方法,在main中,父类的引用father指向了子类的对象son,当我们调用father的getName()方法时,实际上是动态绑定到了子类的getName()上,所以会打印出”son”。

5.再深一点

你是否真正理解了多态呢?请看下面的例子:

什么是java的多态

上面这个例子中,下面四条语句的输出结果是什么呢?

a1.show(b);
a1.show(c);
a2.show(b);
a2.show(c);

结果如下:

 什么是java的多态

对于前两条语句的结果我们很容易理解,那第三条和第四条的,为什么结果和我们想的不一样,不应该是”B and B”吗?要理解这是为什么,我们要先理解下面这句话:

当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。 (但是如果强制把超类转换成子类的话,就可以调用子类中新添加而超类没有的方法了)

看一下标红的那句话,我们知道问题所在了吗?

当运行 a2.show(b) 的时候,实际是要调用一个 show(B obj) 的方法,但是 A 中有这样一个方法吗?没有!但是由于 B 继承自 A,所以会调用 A 中的 show(A obj) 的方法,但是调用时候发现这个方法已经被 B 重写了,所以就会转向来调用 B 中的 show(A obj) 方法。所以才会打印出”B and A”。

实际上这里涉及方法调用的优先问题 ,优先级由高到低依次为:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。让我们来看看它是怎么工作的。

比如,a2.show(b),a2是一个引用变量,类型为A,则this为a2,b是B的一个实例,于是它到类A里面找show(B obj)方法,没有找到,于是到A的super(超类)找,而A没有超类,因此转到第三优先级this.show((super)O),this仍然是a2,这里O为B,(super)O即(super)B即A,因此它到类A里面找show(A obj)的方法,类A有这个方法,但是由于a2引用的是类B的一个对象,B覆盖了A的show(A obj)方法,因此最终锁定到类B的show(A obj),输出为”B and A”。

怎么样?理解了吗?

 

问题还要继续,现在我们再来看上面的分析过程是怎么体现出红色字体那句话的内涵的。它说:当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。还是拿a2.show(b)来说吧。

 

a2是一个引用变量,类型为A,它引用的是B的一个对象,因此这句话的意思是由B来决定调用的是哪个方法。因此应该调用B的show(B obj)从而输出”B and B”才对。但是为什么跟前面的分析得到的结果不相符呢?!问题在于我们不要忽略了蓝色字体的后半部分,那里特别指明:这个被调用的方法必须是在超类中定义过的,也就是被子类覆盖的方法。B里面的show(B obj)在超类A中有定义吗?没有!那就更谈不上被覆盖了。实际上这句话隐藏了一条信息:它仍然是按照方法调用的优先级来确定的。它在类A中找到了show(A obj),如果子类B没有覆盖show(A obj)方法,那么它就调用A的show(A obj)(由于B继承A,虽然没有覆盖这个方法,但从超类A那里继承了这个方法,从某种意义上说,还是由B确定调用的方法,只是方法是在A中实现而已);现在子类B覆盖了show(A obj),因此它最终锁定到B的show(A obj)。这就是那句话的意义所在,到这里,我们可以清晰的理解Java的多态性了。

 

6. 最后一个练习!

看下面的例子:

什么是java的多态

上面例子中的输出是什么呢?答案是:ai ni

有了前一个例子我们就会很容易理解这个例子。在B类中是没有对A中的show方法进行重写,所以当a.show()时调用的是父类中的show方法,父类中show方法调用了show2方法,但是在调用的时候发现show2方法已经被子类重写,因此会调用子类中show2方法,因此输出”ai”。可见,当父类引用指向子类对象的时候,对父类中方法的调用都会绑定到子类中重写后的方法上,如果子类没有对方法进行重写,那么会直接调用父类中的方法,相当于是直接调用从父类继承的方法

还需要注意的一点是子类在重写父类的方法时,方法的访问权限不能更低!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/156582.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 数学建模主成分分析法matlab_主成分分析法建模

    数学建模主成分分析法matlab_主成分分析法建模数学建模方法——主成分分析法Ⅰ.主成分分析:​ 主成分分析(PrincipalComponentAnalysis,PCA),将多个变量通过线性变换以选出较少个数重要变量的一种多元统计分析方法。主成分与原始变量之间的关系:​ (1)主成分保留了原始变量绝大多数信息。​ (2)主成分的个数大大少于原始变量的数目。​ (3)各个主成分之间互不相关。​ (4)每个主成分都是原始变量…

    2022年10月15日
  • Java三大特征

    Java三大特征Java面向对象的三大特征:封装、继承、多态封装和继承几乎都是为多态而准备的一、     封装首先,属性能够描述事物的特征,方法能够描述事物的动作。封装就是把同一类事物的共性(包括属性和方法)归到同一类中,方便使用。封装:封装也称信息隐藏,是指利用抽象数据类型把数据和基于数据的操作封装起来,使其成为一个不可分割的整体,数据隐藏在抽象数据内部,尽可能的隐藏数

  • 《三体》中的经典名句是_三体2黑暗森林中的好词好句

    《三体》中的经典名句是_三体2黑暗森林中的好词好句0.死亡是唯一一座永远亮着的灯塔,不管你向哪里航行,最终都得转向它指引的方向。一切都会逝去,只有死神永。1.弱小和无知不是生存的障碍,傲慢才是!2.有一个故事,说一波外星人来到了地球。他们发现这个

  • 华为P50/P50Pro怎么解锁huawei P50pro屏幕锁开机锁激活设备锁了应该如何强制解除鸿蒙系统刷机解锁方法流程步骤不开机跳过锁屏移除锁定进系统方法经验

    华为P50/P50Pro怎么解锁huawei P50pro屏幕锁开机锁激活设备锁了应该如何强制解除鸿蒙系统刷机解锁方法流程步骤不开机跳过锁屏移除锁定进系统方法经验今天带来一台用户华为P50pro手机强制清除华为账号锁案例分享,这个台手机是用户公司手机,由于前使用者离职后未能退出手机的华为账号和锁屏密码,导致手机无法使用。自己通过简单的恢复出厂设置后,发现手机有华为账号锁无法激活手机,这才联系到刷机爱好者技术人员,给予远程强制刷机移除华为P50pro的账号锁。在此提醒广大用户,登录的华为账号建议绑定经常使用的手机号码,防止无法找回密码从而到时手机无法使用。在刷机解锁过程中需要准备以下工具:链接:百度网盘请输入提取码提取码:8888–来自百度网盘超

  • 如何访问他人电脑上的共享文件夹

    如何访问他人电脑上的共享文件夹

  • Java开发人员必须掌握的Linux命令(三)

    做一个积极的人编码、改bug、提升自己我有一个乐园,面向编程,春暖花开!学习应该是快乐的,在这个乐园中我努力让自己能用简洁易懂(搞笑有趣)的表达来讲解知识或者技术,让学习之旅充满乐趣,这就是写博文的初心。前面写了两篇Linux的命令介绍,地址1 地址2 ,前段时间看了哈利波特的一些电影,突然想到Linux的命令就像哈利波特电影中的魔法一样,都是有魔力的。那么学会Linux的这些命令,我…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号