深入理解Java多态性

看过一些关于Java多态性的文章,参考了很多人的理解,加入了一些自己的看法,整理出来供大家参考,不一定完全正确,欢迎大家批评指正。

(一)相关类


class A {

public String show(D obj){
return ("A and D");
}
public String show(A obj){
return ("A and A");
}
}
class B extends A{
public String show(B obj){
return ("B and B");
}
public String show(A obj){
return ("B and A");
}
}
class C extends B{}
class D extends B{}


(二)问题:以下输出结果是什么?


A a1 = new A();
A a2 = new B();
B b = new B();
C c = new C();
D d = new D();
System.out.println("①="+a1.show(b));// ①
System.out.println("②="+a1.show(c)); // ②
System.out.println("③="+a1.show(d));// ③
System.out.println("④="+a2.show(b)); // ④
System.out.println("⑤="+a2.show(c)); // ⑤
System.out.println("⑥="+a2.show(d)); // ⑥
System.out.println("⑦="+b.show(b)); // ⑦
System.out.println("⑧="+b.show(c)); // ⑧
System.out.println("⑨="+b.show(d)); // ⑨


(三)答案
①=A and A
②=A and A
③=A and D
④=B and A
⑤=B and A
⑥=A and D
⑦=B and B
⑧=B and B
⑨=A and D

(四)分析

①②③比较好理解,一般不会出错。④⑤就有点糊涂了,为什么输出的不是"B and B”呢?!!先来回顾一下多态性。

运行时多态性是面向对象程序设计代码重用的一个最强大机制,Java多态性的概念也可以被说成“一个接口,多个方法”。Java实现运行时多态性的基础是动态方法调度,它是一种在运行时而不是在编译期调用重载方法的机制。

方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写(Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被“屏蔽”了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中Java多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被“屏蔽”了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。

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

好了,先温习到这里,言归正传!实际上这里涉及方法调用的优先问题 ,优先级由高到低依次为:[color=red]this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。[/color]让我们来看看它是怎么工作的。

比如④,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”。

再比如⑧,b.show(c),b是一个引用变量,类型为B,则this为b,c是C的一个实例,于是它到类B找show(C obj)方法,没有找到,转而到B的超类A里面找,A里面也没有,因此也转到第三优先级this.show((super)O),this为b,O为C,(super)O即(super)C即B,因此它到B里面找show(B obj)方法,找到了,由于b引用的是类B的一个对象,因此直接锁定到类B的show(B obj),输出为"B and B”。

按照上面的方法,可以正确得到其他的结果。

问题还要继续,现在我们再来看上面的分析过程是怎么体现出蓝色字体那句话的内涵的。它说:当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。还是拿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的多态性了。
java的面向对象基础(4)——多态 阅读详情

相关推荐

深入理解Java继承与多态性

本文通过对Java中继承和多态性的探讨,深入解析了如何在类的扩展中使用构造函数,并通过具体案例分析了继承层次结构、覆盖与多态的概念。同时,通过对相关代码段的分析,展示了如何在实际编程中应用这些概念,并指出了常见的错误和误解。

weixin_32047493的博客 408

举例说明java多态性_Java多态性举例说明

Java多态性的概念也可以被说成“一个接口,多个方法”。(一)相关类classA...{publicStringshow(Dobj)...{return("AandD");}publicStringshow(Aobj)...{return("AandA");}}classBextendsA...{publicStringshow(Bobj)...{return("Band...

weixin_30164615的博客 593

Java多态例子

1.多态概述 1.1多态是继封装、继承之后,面向对象的三大特性。 2.多态体现为父类引用变量可以指向子类对象。 3.前提条件:必须有子类父类关系。 4.多态的定义与使用格式 定义格式:父类类型 变量名=new 子类类型(); 5.理解: 5.1多态是同一个行为具有多个不同表现形式或形态的能力。 5.2多态就是同一个接口,使用不同的实例而执行不同操作。 7.以七个葫芦娃为例:每个葫芦娃都有不同的战斗方式,需要一个来调用。 (1)...

qq_53508949的博客 587

多态(java

多态是指当父类引用引用的对象不一样的时候表现出的行为是不一样的。

qq_52134698的博客 1996

Java学习笔记——多态(实例详解)

多态是某一事物,在不同时刻体现出来的不同的状态 就比如猫,狗,狼都是动物,我们可以说猫是动物,说狗是动物 但我们不能说动物是猫,动物是狼。也不能说猫是狗,或者狗是狼。 上面这几点都会在多态中体现出来 多态的前提: 类之间要有继承的关系 子类要有对父类方法的重写(不重写也不会报错,但这样体现不出来多态的意义) 父类的引用变量指向子类对象 下面看一个多态的简单例子 package test.DuoTaiDemo; class Animal{ public void eat(){ S

一纸春秋的博客 1万+

深入理解java多态性

深入理解java多态性         昨天看到一个关于多态性的帖子,参考了回帖者的理解,加入了一些自己的看法,整理出来供大家参考,不一定完全正确,欢迎大家批评指正。 (一)相关类 class A ...{          public String show(D obj)...{                 return ("A and D");          }

thinkGhoster的专栏 7万+

java多态性_深入理解java多态性

引言:多态是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码...

weixin_32267129的博客 166

深入理解 Java 中的多态性

多态性为我们的代码带来了极大的便利,其最大的好处就是能够极大地减少代码的冗余。也就是说,在多态的场景下,我们创建了子类的对象,也加载了子类特有的属性和方法,但因为引用类型是父类的,所以无法直接访问子类特有的那些属性和方法。在 Java 编程的语境中,多态性使得同一个操作在不同的对象上会产生不同的执行结果,这为我们编写灵活且可维护性高的代码提供了强大的支持。这是因为当我们通过父类引用指向子类对象时,虽然可以调用被子类重写的方法,但对于属性来说,访问的始终是父类中定义的属性(即使子类中可能也有同名属性)。

qq_69304031的博客 1053

[转载]深入理解java多态性

FROM:http://blog.csdn.net/thinkGhoster/article/details/2307001 昨天看到一个关于多态性的帖子,参考了回帖者的理解,加入了一些自己的看法,整理出来供大家参考,不一定完全正确,欢迎大家批评指正。 (一)相关类 classA...{publicStringshow(Dobj)...{...

121

深入理解java多态性 .

(一)相关类 [code="java"]class A ...{ public String show(D obj)...{ return ("A and D"); } public String show(A obj)...{ return ("A and A"...

SuperWangq的专栏 128
上一篇: jQuery框架获取及设置单选框、多选框、文本框内容
下一篇: MyEclipse常用快捷键
wjboy49
博客等级 码龄19年 1粉丝 149原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值