Java多態性理解


什么是多態

  1. 面向對象的三大特性:封裝、繼承、多態。從一定角度來看,封裝和繼承幾乎都是為多態而准備的。這是我們最后一個概念,也是最重要的知識點。
  2. 多態的定義指允許不同類的對象對同一消息做出響應。即同一消息可以根據發送對象的不同而采用多種不同的行為方式。(發送消息就是函數調用)
  3. 實現多態的技術稱為:動態綁定(dynamic binding),是指在執行期間判斷所引用對象的實際類型,根據其實際的類型調用其相應的方法。
  4. 多態的作用消除類型之間的耦合關系。
  5. 現實中,關於多態的例子不勝枚舉。比方說按下 F1 鍵這個動作,如果當前在 Flash 界面下彈出的就是 AS 3 的幫助文檔;如果當前在 Word 下彈出的就是 Word 幫助;在 Windows 下彈出的就是 Windows 幫助和支持。同一個事件發生在不同的對象上會產生不同的結果。

下面是多態存在的三個必要條件,要求大家做夢時都能背出來!

多態存在的三個必要條件 一、要有繼承; 二、要有重寫; 三、父類引用指向子類對象。

 

 多態的好處

1.可替換性(substitutability)。多態對已存在代碼具有可替換性。例如,多態對圓Circle類工作,對其他任何圓形幾何體,如圓環,也同樣工作。

2.可擴充性(extensibility)。多態對代碼具有可擴充性。增加新的子類不影響已存在類的多態性、繼承性,以及其他特性的運行和操作。實際上新加子類更容易獲得多態功能。例如,在實現了圓錐、半圓錐以及半球體的多態基礎上,很容易增添球體類的多態性。

3.接口性(interface-ability)。多態是超類通過方法簽名,向子類提供了一個共同接口,由子類來完善或者覆蓋它而實現的。如圖8.3 所示。圖中超類Shape規定了兩個實現多態的接口方法,computeArea()以及computeVolume()。子類,如Circle和Sphere為了實現多態,完善或者覆蓋這兩個接口方法。

4.靈活性(flexibility)。它在應用中體現了靈活多樣的操作,提高了使用效率。

5.簡化性(simplicity)。多態簡化對應用軟件的代碼編寫和修改過程,尤其在處理大量對象的運算和操作時,這個特點尤為突出和重要。

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)); ① //a1指向的類時A System.out.println(a1.show(c)); ② System.out.println(a1.show(d)); ③ System.out.println(a2.show(b)); ④ //a2指向的類時B,B類直接超類是A而且重寫了show(A OBJ)。所以當傳入的參數是B對象的時候,調用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)); ⑧ //b指向的類是B,而C,D類的直接超類是B所以調用的是show(B OBJ)。 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
復制代碼

 

接口和抽象類的例子:

對於抽象類和接口,有許多類實現這個接口(或者繼承這個抽象類)。 在調用的時候,用父類引用指向子類對象的方法。然后,調用對象的方法,編譯器就會自動根據這個對象實際屬於哪個實現類, 來調出這個類對於接口或者抽象類的具體實現。
例:

 public class Address {
 private String name; 
 public Address(String name){ this.name = name; }
 public String getName() { return name; }
 public void setName(String name) { this.name = name; }
 }


定義基類(抽象類):

public abstract class Vehicle { 
abstract void go(Address address); 
}
//Car對於基類的實現: 
public class Car extends Vehicle{ 
@Override 
public void go(Address address){ 
System.out.println("Car to " + address.getName());
 }
 }


Plane對於基類的實現: 

public class Plane extends Vehicle{
 @Override 
void go(Address address) 
{ System.out.println("Plane to " + address.getName());
 }
 }


 Driver中多態:

 public void drive(Vehicle v){                  
///多態,父類引用指向子類對象,實際傳過來的是抽象類Vehicle的子類,或者實現類,然后編譯器會根據具體實現類,來找實現方法。 
v.go(new Address("杭州(abstract)"));    ///此方法在具體的實現中被重寫 
}
Test: 
public static void main(String[] args) { 
Driver d = new Driver();
 d.drive(new Plane());   //實際是Plane對象,則編譯器就會找到Plane中,對go的實現 d.drive(new Car());       //實際是Car對象,則編譯器就會找到Plane中,對go的實現
 }

 


輸出結果: Plane to 杭州(abstract) Car to 杭州(abstract)
事實上,這就是多態所起的作用,可以實現控制反轉這在大量的J2EE輕量級框架中被用到,比如Spring的依賴注射機制。 (通過注入不同的bean,來得到不同的實現類)
接口與抽象類的區別:
有個概念,但還沒有想到具體實現。 對於一些共用的,已經有實現了,可以設計成接口。
上面是抽象類,下面把它轉化為接口:
IVehicle.java public interface IVehicle { public void go(Address address); }
CarImpl.java public class CarImpl implements IVehicle{ public void go(Address address) { System.out.println("CarImpl to " +address.getName()); } }
PlameImpl.java public class PlaneImpl implements IVehicle{ public void go(Address address) { System.out.println("PlaneImpl to " + address.getName()); } }
Driver.java ////多態之接口 public void driveI(IVehicle v){ v.go(new Address("杭州(interface)")); }
Test.java ////用接口實現 d.driveI(new PlaneImpl()); d.driveI(new PlaneImpl());
打印結果: PlaneImpl to 杭州(interface) PlaneImpl to 杭州(interface)

 

多態的三要素:1.繼承  2.重寫  3.父類引用指向子類對象

 

以上就是我目前學習中的總結,如有不足之處,還望多多賜教。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM