`
DemoGilbete
  • 浏览: 5384 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

深入理解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的方法是可以改变返回值的类型。

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

好了,先温习到这里,言归正传!实际上这里涉及方法调用的优先问题 ,优先级由高到低依次为: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”。

再比如⑧,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多态

    本文带您通过几个类的示例和讲解来理解Java多态性,Java多态性的概念也可以被说成“一个接口,多个方法

    多态性实现机制在C 与JAVA中的比较分析.pdf

    熟练使用多态性是程序设计者运用面向对象方法进行程序设计的关键,而理解多态性实现机制则是...为充分理解多态性的实现机制,采用比较方法,深入分析比较了C++和java的多态性在使用方法、要点、内部实现流程以及实现...

    Java 多态面试集锦进阶版20道Java多态高难度面试题及详细答案解析

    通过深入理解和掌握Java多态性,可以提升面试者的编程能力和解决问题的能力,从而在面试中展现出更高水平。本文适合准备Java面试的开发者系统学习和巩固多态性相关的知识,提升面试竞争力。为准备面试的开发者提供了...

    深入理解Java:10个示例展示核心概念和用法涵盖了类和对象、继承和多态、接口和实现、异常处理、集合框架、文件操作、多线程、输入

    这个Java文件包含了10个示例代码,旨在深入理解Java的核心概念和用法。每个示例都展示了不同的方面,涵盖了面向对象编程、继承和多态、接口和实现、异常处理、集合框架、文件操作、多线程、输入输出、Lambda表达式和...

    上转型对象体现多态

    深入理解Java中向上转型对象体现的多态,以及面向对象思想

    深入理解Java三大特性中的多态

    多态性是对象多种表现形式的体现。在面向对象中,最常见的多态发生在使用父类的引用来引用子类的对象。下面这篇文章主要给大家深入的介绍了Java三大特性中多态的相关资料,有需要的朋友可以参考借鉴,下面来一起看看...

    《Java开发实战经典》——学习攻略

    3、IO操作:对于大部分的自学者而言,IO操作也许是最难过的一个坎了,如果没有很好的理解抽象类和接口的概念,那么要想充分的理解IO操作是很难的,在整个IO操作之中,完整的体现了Java语言多态性的设计思想,而且在...

    Java开发详解.zip

    020607_【第6章:面向对象(高级)】_对象的多态性笔记.pdf 020608_【第6章:面向对象(高级)】_instanceof关键字笔记.pdf 020609_【第6章:面向对象(高级)】_抽象类与接口的应用笔记.pdf 020610_〖第6章:面向...

    张孝祥Java就业培训教程.pdf

    4.3 对象的多态性 4.4 异常 4.5 包 4.6 访问控制 4.7 使用jar文件 第5章 多线程 5.1 如何创建与理解线程 5.2 多线程的同步 5.3 线程间的通信 5.4 线程生命的控制 第6章 Java API 6.1 理解API的概念 6.2 工具软件的...

    Java编程艺术 PDF

    1.5 对多态性支持的改进 5 1.6 通过字节码保证可移植性和安全性 5 1.7 丰富的Java API 6 1.8 Applet 7 1.9 继续变革 7 第2章 递归下降的表达式解析器 9 2.1 表达式 10 2.2 解析表达式 11 2.3 表达式的解析 11 2.4 ...

    Java抽象类高难度面试题及解析

    此外,我们还讨论了抽象类与接口的结合应用、抽象类的静态方法和内部类、抽象类的多态性等重要概念和技术。 通过研究和解答这些高难度问题,您将提升自己的编程水平,展现出对Java抽象类的深刻理解和掌握。不仅可以...

    疯狂JAVA讲义

    5.7.1 多态性 151 5.7.2 引用变量的强制类型转换 152 5.7.3 instanceof运算符 154 5.8 继承与组合 154 5.8.1 使用继承的注意点 155 5.8.2 利用组合实现复用 156 学生提问:使用组合关系来实现复用时,需要创建...

    java并发编程理论基础精讲

    通过深入学习,您将建立坚实的并发编程基础,能够更好地理解和应对多线程编程中的挑战。 并发编程概述: 引入并发编程的基本概念,解释为什么多线程编程在现代应用中至关重要。 线程和进程: 解释线程和进程的区别,...

    C++编程思想(Thinking in C++)完美版pdf

    第15章 多态性和虚函数 第16章 模板介绍 附录A 编码风格 附录B 编程准则 附录C 推荐读物 索引 第2卷:实用编程技术 出版者的话 专家指导委员会 译者序 前言 第一部分 建立稳定的系统 第1章 异常处理 第2章 防御性...

    java并发编程:线程基础

    通过深入学习,您将建立扎实的多线程编程基础,能够更好地理解和应用多线程编程。 多线程概述: 简要介绍多线程编程的重要性和应用场景。解释为什么多线程可以提高程序性能和资源利用率。 线程的创建: 详细讲解线程...

    完成Java面向对象程序设计实验课的心得体会(1).doc

    通过对Java的了解,我发现它确实有很多方便之处,它集抽象性、封装 性、继承性和多态性于一体,实现了代码重用和代码扩充,提高了软件开发的效率。对 于我们这个专业来说学好Java语言是很重要的,所以在实验的过程中...

    java 编程艺术

    1.5 对多态性支持的改进 5 1.6 通过字节码保证可移植性和安全性 5 1.7 丰富的Java API 6 1.8 Applet 7 1.9 继续变革 7 第2章 递归下降的表达式解析器 9 2.1 表达式 10 2.2 解析表达式 11 2.3 表达式的解析 ...

    完成Java面向对象程序设计实验课的心得体会.doc

    通过对Java的了解,我发现它确实有很多方便之处,它集抽象性、封装 性、继承性和多态性于一体,实现了代码重用和代码扩充,提高了软件开发的效率。对 于我们这个专业来说学好Java语言是很重要的,所以在实验的过程中...

    java毕业实习报告资料.docx

    他们欠缺的主要是两点: (1)不能全面系统的、深入的掌握某种技术,也就是会的挺多,但都是皮毛,不 能满足就业的需要。 (2)没有任何实际的开发经验,完全是想象中学习,考试还行,一到实际开发和 应用就歇菜了...

Global site tag (gtag.js) - Google Analytics