Java三大特性之多态

作者: 一只好奇的茂 | 来源:发表于2017-06-19 14:52 被阅读155次

    介绍

    1. 面向对象的三大特性:
      封装、继承、多态。从一定角度来看,封装和继承几乎都是为多态而准备的。这是我们最后一个概念,也是最重要的知识点。
    2. 多态的定义:
      指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用)
    3. 实现多态的技术:
      动态绑定(dynamic binding),是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。
    4. 多态的作用:
      消除类型之间的耦合关系。
    5. 关于多态的例子:
      比方说按下 F1 键这个动作,如果当前在 Flash 界面下弹出的就是 AS 3 的帮助文档;如果当前在 Word 下弹出的就是 Word 帮助;在 Windows 下弹出的就是 Windows 帮助和支持。同一个事件发生在不同的对象上会产生不同的结果。
    6. 多态存在的三个必要条件:
    • 要有继承
    • 要有重写
    • 父类引用指向子类对象
    1. 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{
    }
    public class Test {
        public static void main(String[] args) {  
            A a1 = new A();  
            A a2 = new B();  
            B b = new B();  
            C c = new C();  
            D d = new D();  
              
            System.out.println("1--" + a1.show(b));  
            System.out.println("2--" + a1.show(c));  
            System.out.println("3--" + a1.show(d));  
            System.out.println("4--" + a2.show(b));  
            System.out.println("5--" + a2.show(c));  
            System.out.println("6--" + a2.show(d));  
            System.out.println("7--" + b.show(b));  
            System.out.println("8--" + b.show(c));  
            System.out.println("9--" + b.show(d));        
        }  
    }
    
    • 结果
    1--A and A
    2--A and A
    3--A and D
    4--B and A
    5--B and A
    6--A and D
    7--B and B
    8--B and B
    9--A and D
    
    • 分析前提
    1. 多态机制遵循的原则概括为:当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法,但是它仍然要根据继承链中方法调用的优先级来确认方法,该优先级为:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。
    2. 向上转型时,父类指向子类引用对象会遗失除与父类对象共有的其他方法,也就是在转型过程中,子类的新有的方法都会遗失掉
    • 分析
      在这里看结果1、2、3还好理解,从4开始就开始糊涂了,对于4来说为什么输出不是“B and B”呢?
      分析4,a2.show(b):
      这里a2是引用变量,为A类型,它引用的是B对象,因此按照上面“分析前提”的意思是说应该由B来决定调用谁的方法,所以a2.show(b)应该要调用B中的show(B obj),产生的结果应该是“B and B”,但是为什么会与前面的运行结果产生差异呢?这里我们忽略了后面那句话“但是这儿被调用的方法必须是在超类中定义过的”,那么show(B obj)在A类中存在吗?根本就不存在!所以这句话在这里不适用?那么难道是这句话错误了?非也!其实这句话还隐含这这句话:它仍然要按照继承链中调用方法的优先级来确认。所以它才会在A类中找到show(A obj),同时由于B重写了该方法所以才会调用B类中的方法,否则就会调用A类中的方法。
      分析5,a2.show(c):
      a2是A类型的引用变量,所以this就代表了A,a2.show(c),它在A类中找发现没有找到,于是到A的超类中找(super),由于A没有超类(Object除外),所以跳到第三级,也就是this.show((super)O),C的超类有B、A,所以(super)O为B、A,this同样是A,这里在A中找到了show(A obj),同时由于a2是B类的一个引用且B类重写了show(A obj),因此最终会调用子类B类的show(A obj)方法,结果也就是B and A。
      分析6、7、8、9
      根据分析前提,同上。

    总结

    1. 向上转型时,父类指向子类引用对象会遗失除与父类对象共有的其他方法,也就是在转型过程中,子类的新有的方法都会遗失掉
    2. 多态机制遵循的原则概括为:当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法,但是它仍然要根据继承链中方法调用的优先级来确认方法,该优先级为:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。

    参考

    深入理解java多态性

    推荐阅读

    Java三大特性之多态
    Java三大特性之继承
    Java三大特性之封装

    相关文章

      网友评论

        本文标题:Java三大特性之多态

        本文链接:https://www.haomeiwen.com/subject/afobqxtx.html