1. 程式人生 > >Java多態總結

Java多態總結

根據 什麽 子類 ash 來看 動態 好處 subst 得出

面向對象的三大特性:封裝、繼承、多態。從一定角度來看,封裝和繼承幾乎都是為多態而準備的。這是最後一個概念,也是最重要的知識點。

1.定義:

多態:指允許不同類的對象對同一消息做出響應。即同一消息可以根據發送對象的不同而采用多種不同的行為方式。(發送消息就是函數調用)

2.實現多態的技術稱為:動態綁定(dynamic binding),是指在執行期間判斷所引用對象的實際類型,根據其實際的類型調用其相應的方法。

3.作用消除類型之間的耦合關系

4.現實中,關於多態的例子不勝枚舉。比方說按下 F1 鍵這個動作,如果當前在 Flash 界面下彈出的就是 AS 3 的幫助文檔;如果當前在 Word 下彈出的就是Word 幫助;在 Windows 下彈出的就是 Windows 幫助和支持。同一個事件發生在不同的對象上會產生不同的結果。

5.下面是多態存在的三個必要條件

多態存在的三個必要條件

一、要有繼承;

二、要有重寫;

三、父類引用指向子類對象。

6.多態的好處

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

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

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

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

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

7.Java中多態的實現方式接口實現,繼承父類進行方法重寫,同一個類中進行方法重載。

8.Java中多態的分類

在java中,多態大致可以分為以下幾種情況:

1)person為父類,student為子類。那麽:person p=new student()

2)fliable為接口,bird為實現接口的類,那麽:fliable f=new bird()

3)fliable為抽象類,bird為繼承fliable的類,那麽:fliablef=new bird()

多態時需要說明p聲明為父類的引用,但他實際為子類引用。但是他只能調用父類中的方法。如果子類中的方法覆蓋了父類方法,那麽將調用父類方法(虛方法調用)。接口多態也是同樣的,也許你會問,如果f要調用自己的方法,那豈不是出錯了?其實這裏也是方法的覆蓋,因為實現接口的子類肯定會實現接口中的方法, 所以此種情況下調用的是bird中的方法。但是如果bird有一個方法在接口中沒有定義,那麽f不能調用。

9.instanceof運算符

java語言的多態機制導致了引用變量的聲明類型和其實際引用對象的類型可能不一致,再結合虛方法調用規則可以得出結論:聲明為同種類型的兩個引用變量調用同一個方法時也可能會有不同的行為。這裏就引入了instanceof運算符。

那麽如果我聲明了person p=new student();我想將p轉為student的可不可以?當然可以,但是就得強制轉換了(兒子想成為父親直接來,父親想成為兒子你就強來)。

通常在強制轉換時加上instanceof來判斷。

if(p instanceof student) { student s=studentp}

多態貫穿於java整個學習,比如在異常處理時寫catch語句,我們規定必須子類異常寫在前,父類異常寫在後。為什麽呢?原因就是多態了。我們的 catch語句格式:catch(Exception e)。java程序在產生異常時會自動生成一個異常對象,如果先產生一個子類異常,並且父類異常寫在前,那麽根據多態肯定會執行此catch語句,執行完 一條catch語句後將會跳出。

10.實例

關於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{}

class E

{

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(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

****有個好心人的解答****

該問題的關鍵有兩點:

一是子類與父類的關系,二是重載方法的調用問題。

子類對象可以直接當成父類對象使用,但反過來就不可以。舉例來說,人是父類,學生是人的子類,所以學生對象一定具備人對象的屬性,但是人對象就未必具有學 生對象的特性。所以學生對象可以當做人對象來使用,但是人對象就不能當做學生對象使用。註意當把子類對象當成父類對象使用時,子類對象將失去所有的子類特 性,只保留與父類同名的屬性和方法(同名方法不僅是函數名相同,而且參數類型也要一樣,否則不予保留)。

一個類中如果定義了重載的方法,則系統在調用方法時,會根據參數的類型自動選擇調用合適的方法。

1) a1.shows(b),A中沒有含有B類參數的方法,但是含有A類參數的方法,根據子類對象父類可用的原則,所以調用方法

public String show(A obj)...{return ("A and A");}

2) a1.show(c),C類是B類的子類,而B類又是A類的子類,所以C類對象可以當制作A類對象使用。結果同上。

3) a1.show(d),根據參數類型直接調用A中的方法

public String show(D obj)...{

return ("A and D");}

4) a2.show(b)a2本來是一個B對象,但是將其賦給了A類變量,所以a2只保留了與父類A同名的屬性和方法。a2.show(b)調用B類中的保留的與父類同名同參方法

public String show(A obj)...{

return ("B and A");

}

5) a2.show(c)B類的保留方法中沒有C類參數方法,但是有含有C的父類B的參數方法,所以調用的方法

public String show(A obj)...{

return ("B and A");

}

我覺得這樣解釋更合理:a2本來是類B的一個對象,但是又將值賦給了類ACB的子類,BA的子類,因此a2保留了類B中與A同名的屬性和方法。

6) a2.show(d),調用的是A類中的

public String show(D obj)...{

return ("A and D");

}

7) b.show(b),調用B類中的

public String show(B obj)...{

return ("B and B");

}

8) b.show(c)B類中沒有C類參數的方法,但是有B類參數的方法,所以調用方法

public String show(B obj)...{

return ("B and B");

}

9) b.show(d),解釋同8

Java多態總結