Java--再次理解多态

Java中多态性(polymorphism)的实现

什么是多态

   1、 面向对象的三大特性:封装、继承、多态。从一定角度来看,封装和继承几乎都是为多态而准备的。这是我们最后一个概念,也是最重要的知识点。
       多态的定义:指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用)
      实现多态的技术称为:动态绑定(dynamic binding),是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。
      多态的作用:消除类型之间的耦合关系。

多态的实现条件:

  继承、重写、父类引用指向子类对象。

网络上面常见的对多态的理解:

 多态性有两种:

  1)编译时多态性

    对于多个同名方法,如果在编译时能够确定执行同名方法中的哪一个,则称为编译时多态性.

  2)运行时多态性

    如果在编译时不能确定,只能在运行时才能确定执行多个同名方法中的哪一个,则称为运行时多态性.

上面的划分方法个人不敢苟同。---编译期的方法重载不应该称之为多态,这种方法重载是在编译期已经确定的事情,不具备动态性,多态是针对程序员而言的,而不是程序,多态是可扩展的(在不改变原码的基础上,实现更好的扩展)。所以就像上面所说,动态绑定(Dynamic Binding)--在运行期来决定要做什么,而不是在编译期。Runtime polymorphism (dynamic binding or method overriding)

多态的好处:

  更高的可扩展性。降低了耦合性。

多态的经典实例:

(一)相关类

 1     class A ...{  
 2              public String show(D obj)...{  
 3                     return ("A and D");  
 4              }   
 5              public String show(A obj)...{  
 6                     return ("A and A");  
 7              }   
 8     }   
 9     class B extends A...{  
10              public String show(B obj)...{  
11                     return ("B and B");  
12              }  
13              public String show(A obj)...{  
14                     return ("B and A");  
15              }   
16     }  
17     class C extends B...{}   
18     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


解析:

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

+--->上面的这句话比较重要,两层意思++

看第④个  a2.show(b) a2是一个引用变量,类型为A,它引用的是B的一个对象,因此这句话的意思是由B来决定调用的是哪个方法。因此应该调用B的show(B obj)从而输出"B and B”才对。但是为什么跟前面的分析得到的结果不相符呢?!问题在于我们不要忽略了上面红色字体的部分,那里特别指明:这个被调用的方法必须是在超类中定义 过的,也就是被子类覆盖的方法。B里面的show(B obj)在超类A中有定义吗?没有!那就更谈不上被覆盖了。

实际上,在多态中涉及方法调用的优先问题 ,优先级由高到低依次为:

this.show(O)  ---->   super.show(O) --->  this.show((super)O) ---> super.show((super)O)。

这种优先级是建立在满足上面条件的基础上。

原文地址:https://www.cnblogs.com/plxx/p/4523953.html