`
xixian
  • 浏览: 215381 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

深入理解多态(转载)

    博客分类:
  • java
阅读更多
转载于
http://blog.csdn.net/thinkghoster/archive/2008/04/19/2307001.aspx

        昨天看到一个关于多态性的帖子,参考了回帖者的理解,加入了一些自己的看法,整理出来供大家参考,不一定完全正确,欢迎大家批评指正。

(一)相关类

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实现运行时多态性的基础是动态方法调度,它是一种在运行时而不是在编译期调用重载方法的机制。

        方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写(Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被“屏蔽”了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (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)。这就是那句话的意义所在。
分享到:
评论

相关推荐

    转载:软件开发者面试百问

    - 多态与委派:在面向对象编程中,多态提供了动态绑定,委派用于委托任务给其他对象。 5. **算法与数据结构**: - 判断2的幂、奇偶性:基础算法应用。 - 链表操作:查找中间元素等,体现链表的特性。 - 文件...

    java面试资料(转载)

    面试官可能会询问抽象类和接口的区别,方法的重写和重载,以及如何利用多态优化代码。 日期和时间的处理是Java程序中常见的需求。早期的java.util.Date和Calendar类由于设计复杂,现在已经推荐使用java.time包下的...

    C++的学习方法及书籍推荐 (转载).doc

    此外,还有其他适合不同水平读者的书籍,如《C++ Primer》和《Effective C++》等,这些书籍可以帮助你逐步深入理解和掌握C++。 总之,学习C++不仅需要掌握语法,还要理解其设计哲学和核心概念,如类型系统、面向...

    java编程事项(转载收集整理版)

    理解类的定义、构造函数、封装、继承和多态是Java编程的基础。同时,接口也是Java中实现多态性的重要方式。 3. **异常处理**:Java的异常处理机制是通过try-catch-finally语句块来实现的。理解如何正确抛出和捕获...

    高质量C++编程指南(转载-中文).pdf

    该指南涵盖了从文件结构到编码风格,从命名规则到内存管理,以及C++语言特性的深度探讨等多个方面,下面我们将深入解读其核心知识点。 ### 文件结构与版式 - **版权和版本声明**:在每个文件头部清晰标注版权信息...

    《PHP网络编程从入门到精通》代码

    这本书涵盖了从基础语法到高级特性的广泛内容,通过实例和实践项目,让学习者能够深入理解PHP网络编程的精髓。 PHP(Hypertext Preprocessor)是一种广泛使用的开源脚本语言,特别适合于Web开发,可嵌入到HTML中。...

    一米阳光项目转载phpwind668—关于PHP

    5. 错误与异常处理:理解错误报告级别和如何捕获并处理异常。 6. 类与对象:PHP 5 引入了面向对象编程,包括类、对象、继承、封装和多态。 【PHPWind 6.68 功能特性】 PHPWind 6.68 版本包含以下主要功能: 1. ...

    Java面试题

    深入讨论抽象类、接口、访问修饰符的区别和使用场景,以及如何利用多态实现动态绑定。 3. **集合框架**:重点掌握ArrayList、LinkedList、HashSet、HashMap等常见集合的内部结构和操作原理。了解List、Set、Map接口...

    c#语言版数据结构(转载)

    - **面向对象**:C#是完全面向对象的编程语言,支持封装、继承和多态等特性。 - **高效性**:通过.NET Framework的运行环境,C#能够提供高性能的应用程序。 - **模板化**:C#支持泛型编程,允许开发者编写通用的代码...

    Java面试资料大集合

    及c-c++面试试题(转载 ) - happyfish - BlogJava.mht》以及《Java常见面试题.txt》等文件,您可以深入理解这些知识点,并在面试中展现出扎实的Java技能。同时,持续学习和实践,将使您在Java开发领域更加游刃有余。

    csharpllksrc

    理解类、对象、继承、封装和多态等概念是必要的。 2. **Windows Forms**:在Visual Studio中,我们通常使用Windows Forms来构建桌面应用程序的用户界面。了解控件布局、事件处理和用户交互是关键。 3. **GDI+** 或...

    c++沉思录.pdf c++学习的必备数据,

    虽然给出的部分内容主要是关于版权、转载规定以及联系方式等,并没有直接涉及技术内容,但我们仍然可以根据文档标题、描述及标签来展开相关的C++知识点。 ### C++编程语言简介 C++是一种通用的多范式编程语言,它...

    EEE-eee.zip资源包

    同时,描述中提到的"转载需申请"表明其中的内容可能受到版权保护,若要用于其他目的,应当获得原作者的许可。 在Python编程中,有许多重要的知识点,我们可以从以下几个方面来展开讨论: 1. **基本语法**:Python...

    c#学习完全手册,适用于初学者

    本文将深入解析这份手册中的核心概念,帮助读者构建坚实的知识体系。 C#,全称C Sharp,是由微软公司为.NET框架开发的一种面向对象的编程语言,它的设计目标是简洁、类型安全和性能高效。C#语言借鉴了C++和Java的...

    JAVA文章精选542个(txt) 免费分享

    这篇文章可能包含Java编程的简单示例,用于解释基本概念,如类、对象、继承、多态等,对于初学者来说是非常有用的参考资料。 5. **转载--微软98年关于MTS和EJB的比较说明文件.其实Sun也有类似的对比文件,我忘记在...

    OpenFOAM研究博文集

    6. pimple 算法简述 (2009-09-30 09:22:33) 转载 .......................................... 7. 粒子方法讨论版开版 .................................................................................. 8. ...

Global site tag (gtag.js) - Google Analytics