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)); ①
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的父類A的參數方法,所以調用的方法
public String show(A obj)...{
return ("B and 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
你要明白這一點,多態這個做法..多態的作用就是能使你的程序更通用.
就比如:A a = new B;..這代碼只能B只能是A的子類或子類的子子類也性.多態你所編寫的類型(即A a;)必須是B你上級.換一種說法就比如:A就是動物,B就是貓,你可以把這隻貓看作是動物.這樣行吧.但你不能把一直動物看作是貓吧.即你所定義的類型必須是實際對象的父類,或是有間接的實現和繼承的關係.

例子:A a = new B;就是說B要是間接或直接的繼承類和實現接口.方可這樣寫.

1.第一個輸出調用語句: a1.show(b); 你上面答案是"A and A" ;

你先看看: A a2 = new B(); 這裏是泛化了吧.也就是說"B"類型可以說是"A"類型.
再看看: A a1 = new A(); 如果再調用a1.show(b);這裏這個方法傳進來的參數是"b"(即: 'B b = new B()');那麼b你可以看作是個"A"類型的是吧?.可是A類裏面有兩個show()方法即方法重載.
請先看第一個方法:public String show(D obj)
方法裏面接受的參數是D類型的.那麼你能把B類型的看作是D類性的嗎(即:你不可能把一隻動物看作是貓吧.)? 即D類型不是B類型的父類.
再看看第二個方法:public String show(A obj)
這個方法就不用說了.這方法接受的參數是A類型的.那麼B繼承了A.也就可以說B類型的可以泛化成A類型的.還個角度說,就是貓可以看作是一個動物吧.
所以.第一個輸出system.out.print(a1.show(b)),這結果自然是:"A and A"

以現實中的事情舉個例子:

假設有一個“小提琴演奏者”類,有一個“鋼琴演奏者”類,還有一個“薩克斯演奏者”類。它們都是彈奏樂器的,都繼承自“樂器演奏者”類。“樂器演奏者”類有個方法叫做“演奏”。三種不同的子類有不同的“演奏”方法實現(拉、彈、吹)。

那麼指揮家如果要指揮一個交響樂,那麼有兩個辦法:
一,分別說“小提琴拉起來”、“鋼琴彈起來”、“薩克斯吹起來”
二,只需要說一句“樂器們都演奏起來”

顯然第一種方法是很笨拙的。因爲指揮家不需要知道每種樂器演奏者具體怎麼樣去演奏樂器(是吹還是彈還是拉),他只需要指揮就可以了。因此應當採用第二種做法。
那麼如何實現第二種做法呢?那就是把三種樂器演奏者子類看成是“樂器演奏者”父類。指揮家只需要調用“演奏”方法就可以了。至於具體是怎麼去演奏,指揮家是不管的。

雖然代碼上寫的是把具體的演奏者子類看成了父類,調用的是父類的“演奏”方法,但是因爲子類繼承了父類的“演奏”方法並且重寫爲更加具體的實現(拉或者彈或者吹),創建實例的時候創建的是子類的實例(構造方法是子類的,只不過看成是父類去用),所以實際執行的時候會去調用子類的“演奏”方法。因此,究竟是該拉還是該彈還是該吹,指揮家不必在意,這個判斷由java虛擬機完成了。

這個就是一個多態的應用

綜合各個方面的問題,我個人總結了其它人的答案,並且加入些容易理解的解釋,希望對你有好處
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同名的屬性和方法。就是說只能調用 public String show(D obj)...{
return ("A and D");
}
和 public String show(A obj)...{
return ("B and A");
}
方法根據子類對象父類可用的原則a2.show(b)調用後者,所以:public String show(A obj)...{
return ("B and A");
}

5 a2.show(c),B類的保留方法中沒有C類參數方法,但是有含有C的父類A的參數方法,所以調用的方法
public String show(A obj)...{
return ("B and A");
} 備註4和5的關係類似於1和2的關係
6 a2.show(d),調用的是A類中的(爲什麼調用A類的方法,在4中已經說明)
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
發佈了41 篇原創文章 · 獲贊 2 · 訪問量 2984
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章