Java多態

1.Java中除了static和final方法外,其他所有的方法都是運行時綁定的。private方法都被隱式指定爲final的,因此final的方法不會在運行時綁定。當在派生類中重寫基類中static、final、或private方法時,實質上是創建了一個新的方法。

 

2.在派生類中,對於基類中的private方法,最好採用不同的名字。

 

3.包含抽象方法的類叫做抽象類。注意定義裏面包含這樣的意思,只要類中包含一個抽象方法,該類就是抽象類。抽象類在派生中就是作爲基類的角色,爲不同的子類提供通用的接口。

 

4.對象清理的順序和創建的順序相反,當然前提是自己想手動清理對象,因爲大家都知道Java垃圾回收器。

 

5.在基類的構造方法中小心調用基類中被重寫的方法,這裏涉及到對象初始化順序。

 

6.構造方法是被隱式聲明爲static方法。

 

7.用繼承表達行爲間的差異,用字段表達狀態上的變化。

 

在JAVA中有兩種多態是指:運行時多態和編譯時多態。

 

關於類的多態性簡介如下:

多態(polymorphism)意爲一個名字可具有多種語義.在程序設計語言中,多態性是指”一種定義,多種實現”.例如,運算符+有多種含義,究竟執行哪種運算取決於參加運算的操作數類型:

1+2 //加法運算符

“1” + “2” //字符串連接運算,操作數是字符串

多態性是面向對象的核心特徵之一,類的多態性提供類中成員設計的靈活性和方法執行的多樣性.

1、類多態性表現

(1)方法重載

重載表現爲同一個類中方法的多態性.一個類生命多個重載方法就是爲一種功能提供多種實現.編譯時,根據方法實際參數的數據類型/個數和次序,決定究竟應該執行重載方法中的哪一個.

(2)子類重定義從父類繼承來的成員

當子類從父類繼承來的成員不適合子類時,子類不能刪除它們,但可以重定義它們,使弗雷成員適應子類的新需求.子類重定義父類成員,同名成員在父類與子類之間表現出多態性,父類對象引用父類成員,子類對象引用子類成員,不會產生衝突和混亂.

子類可重定義父類的同名成員變量,稱子類隱藏父類成員變量.子類也可以重定義父類的同名成員方法,當子類方法的參數列表與父類方法參數列表完全相同時,稱爲子類方法覆蓋(override)父類方法。覆蓋父類方法時,子類方法的訪問權限不能小於父類方法的權限。

由於Object類的equals()方法比較兩個對象的引用是否相等而不是值是否相等,因此一個類要覆蓋Object類的equals()方法,提供本類兩個對象比較相等方法.

覆蓋表現爲父類與子類之間方法的多態性.java 尋找執行方法的原則是:從對象所屬的類開始,尋找匹配的方法執行,如果當前類中沒有匹配的方法,則逐層向上依次在父類或祖先類中尋找匹配方法,直到Object類.

 

2、super 引用

在子類的成員方法中,可以使用代詞super引用父類成員.super引用的語法如下:

super([參數列表]) //在子類的構造方法體中,調用父類的構造方法

super.成員變量 //當子類隱藏父類成員變量時,引用父類同名成員變量

super.成員方法([參數列表]) //當子類覆蓋父類成員方法時,調用父類同名成員方法

*注意:super引用沒有單獨使用的語法


3、多態性有兩種:

1)編譯時多態性

對於多個同名方法,如果在編譯時能夠確定執行同名方法中的哪一個,則稱爲編譯時多態性.

2)運行時多態性

如果在編譯時不能確定,只能在運行時才能確定執行多個同名方法中的哪一個,則稱爲運行時多態性.


方法覆蓋表現出兩種多態性,當對象獲得本類實例時,爲編譯時多態性,否則爲運行時多態性,例如:

XXXX x1 = new XXXX(參數列表); //對象獲得本類實例,對象與其引用的實例類型一致

XXX xx1 = new XXX(參數列表);

x1.toString(); //編譯時多態性,執行XXX類的方法.

xx1.toString(); //編譯時多態性,執行XXXX類覆蓋的方法.

XXXX爲XXX的父類.

由於子類對象既是父類對象,父類對象與子類對象之間具有賦值相容性,父類對象能夠被賦值爲子類對象.例如,

XXXX x2 = new XXX(參數列表); //父類對象獲得子類實例,子類對象即是父類對象

x2.toString(); //運行時多態

 

x2聲明爲父類對象卻獲得子類XXX的實例,那麼x2.toString()究竟執行父類方法還是執行子類覆蓋的方法呢?

這分爲兩種情況:

取決於子類是否覆蓋父類方法.如果子類覆蓋父類方法,則執行子類方法;

如果沒有覆蓋,則執行父類方法.

在編譯時,僅僅依據對象所屬的類,系統無法確定到底應該執行那個類的方法,只有運行時才能確定,因此這是運行時多態.

父類對象並不能執行所有的子類方法,只能執行那些父類中聲明/子類覆蓋的子類方法.

 

 

 

在這樣一個體系中,多態表現出多種形式的能力。通用多態引用有相同結構類型的大量對象,他們有着共同的特徵。特定的多態涉及的是小部分沒有相同特徵的對象。四種多態可做以下描述:

  強制的:一種隱式做類型轉換的方法。

  重載的:將一個標誌符用作多個意義。

  參數的:爲不同類型的參數提供相同的操作。

  包含的:類包含關係的抽象操作。

  我將在講述子類型多態前簡單介紹一下這幾種多態。

  強制的多態

  強制多態隱式的將參數按某種方法,轉換成編譯器認爲正確的類型以避免錯誤。在以下的表達式中,編譯器必須決定二元運算符‘+’所應做的工作:

  2.0 + 2.0

  2.0 + 2

  2.0 + "2"

  第一個表達式將兩個double的操作數相加;Java中特別聲明瞭這種用法。

  第二個表達式將double型和int相加。Java中沒有明確定義這種運算。不過,編譯器隱式的將第二個操作數轉換爲double型,並作double型的加法。做對程序員來說十分方便,否則將會拋出一個編譯錯誤,或者強制程序員顯式的將int轉換爲double。

  第三個表達式將double與一個String相加。Java中同樣沒有定義這樣的操作。所以,編譯器將double轉換成String類型,並將他們做串聯。

  強制多態也會發生在方法調用中。假設類Derived繼承了類Base,類C有一個方法,原型爲m(Base),在下面的代碼中,編譯器隱式的將 Derived類的對象derived轉化爲Base類的對象。這種隱式的轉換使m(Base)方法使用所有能轉換成Base類的所有參數。

C c = new C();

Derived derived = new Derived();

c.m( derived );

  並且,隱式的強制轉換,可以避免類型轉換的麻煩,減少編譯錯誤。當然,編譯器仍然會優先驗證符合定義的對象類型。

  重載的多態

  重載允許用相同的運算符或方法,去表示截然不同的意義。‘+’在上面的程序中有兩個意思:兩個double型的數相加;兩個串相連。另外還有整型相加,長整型,等等。這些運算符的重載,依賴於編譯器根據上下文做出的選擇。以往的編譯器會把操作數隱式轉換爲完全符合操作符的類型。雖然Java明確支持重載,但不支持用戶定義的操作符重載。

  Java支持用戶定義的函數重載。一個類中可以有相同名字的方法,這些方法可以有不同的意義。這些重載的方法中,必須滿足參數數目不同,相同位置上的參數類型不同。這些不同可以幫助編譯器區分不同版本的方法。

  編譯器以這種唯一表示的特徵來表示不同的方法,比用名字表示更爲有效。據此,所有的多態行爲都能編譯通過。

  強制和重載的多態都被分類爲特定的多態,因爲這些多態都是在特定的意義上的。這些被劃入多態的特性給程序員帶來了很大的方便。強制多態排除了麻煩的類型和編譯錯誤。重載多態像一塊糖,允許程序員用相同的名字表示不同的方法,很方便。

  參數的多態

  參數多態允許把許多類型抽象成單一的表示。例如,List抽象類中,描述了一組具有同樣特徵的對象,提供了一個通用的模板。你可以通過指定一種類型以重用這個抽象類。這些參數可以是任何用戶定義的類型,大量的用戶可以使用這個抽象類,因此參數多態毫無疑問的成爲最強大的多態。

  乍一看,上面抽象類好像是java.util.List的功能。然而,Java實際上並不支持真正的安全類型風格的參數多態,這也是 java.util.List和java.util的其他集合類是用原始的java.lang.Object寫的原因(參考我的文章"A Primordial Interface?" 以獲得更多細節)。Java的單根繼承方式解決了部分問題,但沒有發揮出參數多態的全部功能。Eric Allen有一篇精彩的文章“Behold the Power of Parametric Polymorphism”,描述了Java通用類型的需求,並建議給Sun的Java規格需求#000014號文檔"Add Generic Types to the Java Programming Language."(參考資源鏈接)

  包含的多態

  包含多態通過值的類型和集合的包含關係實現了多態的行爲.在包括Java在內的衆多面嚮對象語言中,包含關係是子類型的。所以,Java的包含多態是子類型的多態。

  在早期,Java開發者們所提及的多態就特指子類型的多態。通過一種面向類型的觀點,我們可以看到子類型多態的強大功能。以下的文章中我們將仔細探討這個問題。爲簡明起見,下文中的多態均指包含多態。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章