Java三大特性之多态

介绍

  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三大特性之封装

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 引用多态的一个好例子 让我们分析一下,理清其中各个类的继承关系 那我们开始分析输出A a1 = new A();这...
    BasilQin阅读 16,029评论 3 7
  • 多态,大概每个人都知道。但是,又有几个人真的理解什么是多态、多态有哪些细节呢?如果你看到这篇文章的名字,脑海中对多...
    Sharember阅读 4,731评论 4 30
  • 写在前面 由于找工作的原因,最近几个月都没有更新博客了。。。这篇可能是今年最后一篇总结类的博文了,希望能够写的好点...
    niaoge2016阅读 9,192评论 1 52
  • 那在春风里起舞的枝桠, 将娇小的花蕾亲吻, 娇艳的茉莉花, 羞涩地将花蕊吐露, 那散发出的第一缕清香, 似已顺着叶...
    四夕白水阅读 315评论 0 0
  • 北方某市的初春,市政府宣传部的公务员李大壮的父母打来电话,说家里的房子要拆迁,要来市里住两年,等新房子盖好...
    我的名字也叫红阅读 1,069评论 0 0