java 多型題目練習
java多型性
多型分兩種:
(1) 編譯時多型(設計時多型):方法過載。
(2) 執行時多型:JAVA執行時系統根據呼叫該方法的例項的型別來決定選擇呼叫哪個方法則被稱為執行時多型。(我們平時說得多的事執行時多型,所以多型主要也是指執行時多型)
執行時多型存在的三個必要條件:
一、要有繼承(包括介面的實現);
二、要有重寫;
三、父類引用指向子類物件。
多型的好處:
1.可替換性(substitutability)。多型對已存在程式碼具有可替換性。例如,多型對圓Circle類工作,對其他任何圓形幾何體,如圓環,也同樣工作。
2.可擴充性(extensibility)。多型對程式碼具有可擴充性。增加新的子類不影響已存在類的多型性、繼承性,以及其他特性的執行和操作。實際上新加子類更容易獲得多型功能。例如,在實現了圓錐、半圓錐以及半球體的多型基礎上,很容易增添球體類的多型性。
3.介面性(interface-ability)。多型是超類通過方法簽名,向子類提供了一個共同介面,由子類來完善或者覆蓋它而實現的。如圖8.3 所示。圖中超類Shape規定了兩個實現多型的介面方法,computeArea()以及computeVolume()。子類,如Circle和Sphere為了實現多型,完善或者覆蓋這兩個介面方法。
4.靈活性(flexibility)。它在應用中體現了靈活多樣的操作,提高了使用效率。
5.簡化性(simplicity)。多型簡化對應用軟體的程式碼編寫和修改過程,尤其在處理大量物件的運算和操作時,這個特點尤為突出和重要。
注意:優先順序從高到低:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。
題目:
package arithmetic; public class duotai { class A { public String show(D obj) { return ("A and D"); } public String show(A obj) { return ("A and A"); } } class B extends A { // B可以重寫A public String show(B obj) { return ("B and B"); } // 重寫A方法了嗎? public String show(A obj) { return ("B and A"); } } class C extends B { } class D extends B { } public static void main(String[] args) { duotai outerclass = new duotai(); A a1 = outerclass.new A(); A a2 = outerclass.new B(); B b = outerclass.new B(); C c = outerclass.new C(); D d = outerclass.new D(); System.out.println("1:" + a1.show(b)); System.out.println("2:" + a1.show(c)); System.out.println("3:" + a1.show(d)); System.out.println("4:" + a2.show(b)); System.out.println("5:" + a2.show(c)); System.out.println("6:" + a2.show(d)); System.out.println("7:" + b.show(b)); System.out.println("8:" + b.show(c)); System.out.println("9:" + b.show(d)); } }
輸出結果
1:A and A
2:A and A
3:A and D
4:B and A
5:B and A
6:A and D
7:B and B
8:B and B
9:A and D
分析:
做這種題的話要時時刻刻使用那個優先順序順序:
對於第一題:
a1是A類的一個例項化物件,所以this指向A,然後查詢this.show(b),由於沒有這個方法,所以到super.show(b),但是由於A類沒有超類了,所以到this.show(super b),由於b的超類是A,所以相當於this.show(A),然後在A類中查詢到了這個方法,於是輸出A and A。
對於第二題:
同樣,a1是A類的例項化物件,所以this指向A,然後在A類中查詢this.show(C)方法,由於沒有這個方法,所以到了super.show(C),由於A類的超類裡面找,但是A沒有超類,所以到了this.show(super C),由於C的超類是B所以在A類裡面查詢this.show(B)方法,也沒找到,然後B也有超類,就是A,所以查詢this.show(A),找到了,於是輸出A and A;
對於第三題:
同樣,a1是A類的例項化物件,所以this指向A,然後在A類中找到this.show(D)方法,找到了,所以就輸出A and D;
對於第四題:
a2是B類的引用物件,型別為A,所以this指向A類,然後在A類裡面找this.show(B)方法,沒有找到,所以到了super.show(B),由於A類沒有超類,所以到了this.show(super B),B的超類是A,即super B = A,所以執行方法this。show(A),在A方法裡面找show(A),找到了,但是由於a2是一個類B的引用物件,而B類裡面覆蓋了A類的show(A)方法,所以最終執行的是B類裡面的show(A)方法,即輸出B and A;
對於第五題:
a2是B類的引用物件,型別為A,所以this指向A類,然後在A類裡面找this.show(C)方法,沒有找到,所以到了super.show(C)方法,由於A類沒有超類,所以到了this.show(super C),C的超類是B,所以在A類裡面找show(B),同樣沒有找到,發現B還有超類,即A,所以還繼續在A類裡面找show(A)方法,找到了,但是由於a2是一個類B的引用物件,而B類裡面覆蓋了A類的show(A)方法,所以最終執行的是B類裡面的show(A)方法,即輸出B and A;
對於第六題:
a2是B類的引用物件,型別為A,所以this指向A類,然後在A類裡面找this.show(D)方法,找到了,但是由於a2是一個類B的引用物件,所以在B類裡面查詢有沒有覆蓋show(D)方法,沒有,所以執行的是A類裡面的show(D)方法,即輸出A and D;
對於第七題:
b是B類的一個例項化物件,首相執行this.show(B),在B類裡面找show(B)方法,找到了,直接輸出B and B;
對於第八題:
b是B類的一個例項化物件,首相執行this.show(C),在B類裡面找show(C)方法,沒有找到,所以到了super.show(c),B的超類是A,所以在A類中找show(C)方法,沒有找到,於是到了this.show(super C),C的超類是B,所以在B類中找show(B)f方法,找到了,所以執行B類中的show(B)方法輸出B and B;
對於第九題:
b是B類的一個例項化物件,首相執行this.show(D),在B類裡面找show(D)方法,沒有找到,於是到了super.show(D),B的超類是A類,所以在A類裡面找show(D)方法,找到了,輸出A and D;