- 任何可以被測試通過不只一個IS-A的Java Object就是Polymorphism
- 除了Object Class的物件外,其他所有Java Object都是Polymorphism,因為他們可以通過IS-A測試。例如:PS4是一種(IS-A)PS4, PS4是一種(IS-An)Object
- 存取Object的唯一方法:使用reference variable
- reference variable一旦宣告就不能夠更改type(但可以改變reference object裡的內容)
- reference variable一但決定了type,就可以使用該type的method
- reference variable可以重新assign另一個object(除非reference variable是final),但要注意的是,assign的type必須是原本object的superclass
思考以下情境:
假設現在有兩種遊戲機Class,分別是PS4 Class和Xbox Class,這兩個都是一個遊戲機器,所以他們都extends GameEntmtEquip。但今天有touchPad()的只有PS4 Class,則要如何處理繼承?以下有幾種想法:
- 把touchPad()寫入GameEntmtEquip Class,只讓有touchPad()的Class實作 >> 錯Wrong! 容易出錯,減少GameEntmtEquip cohesion(內聚力),也會讓其他GameEntmtEquip subClass認為有機會使用touchPad()
- 建立一個TouchPad的Class,在裡面寫touchPad(),並且只讓PS4 Class繼承 TouchPad Class,也就是 PS4 extends GameEntmtEquip and TouchPad | Xbox extends GameEntmtEquip >> Wrong! Java只有single inheritance,意指一個Class只能有一個immediate superclass(直接父類別),但注意可以有多個祖先
- 建立一個TouchPad interface,讓有touchPad()需求的Class實作此interface >> Correct!
- 一個reference variable可以被宣告成class type或interface type
取第三個方法,設計如下:
TouchPad interface
TouchPad interface
public interface TouchPad { void touchPad(); }
superClass GameEntmtEquip
public abstract class GameEntmtEquip { abstract void playGame(); }XBox Class
public class XBox extends GameEntmtEquip{ public void playGame() {...} }
public class PS4 extends GameEntmtEquip implements TouchPad { @Override public void playGame() { /*...*/ } @Override public void touchPad() { /*...*/ } }現在,PS4 reference variable就是polymorphism,因為他可以通過以下任一個IS-A
- PS4 IS-A Object (PS4 extends Object)
- PS4 IS-A GameEntmtEquip (PS4 extends GameEntmtEquip)
- PS4 IS-A TouchPad (PS4 implements TouchPad)
- PS4 IS-A PS4
下面所有情況的variable reference都是正確
- 不論object的type為何(ps4),編譯器只依靠reference variable的宣告type(此處為o或ga或tp或ps4)呼叫可使用的method。
PS4 ps4 = new PS4(); Object o = ps4; GameEntmtEquip ga = ps4; TouchPad tp = ps4;
- 範例中有四個reference variable,他是ps4, o, ga, tp
- 範例中只有一個object,他是ps4- o, ga, tp, ps4都指向ps4這個object
- 所以上述只有ps4和ga可以呼叫playGame(),因為看的是reference variable的type
- 不論reference variable是什麼type或interface,都可以使用Object內的methods
- JVM還是知道ps4 object的真實type,所以如果GameEntmtEquip和PS4都有playGame()的程式碼,則
ga.playGame();
ps4.playGame();
兩者都會使用PS4所實作的程式碼來執行。因為JVM會去呼叫該object的真實型別看看有沒有被override,若有,就會使用。
- 注意!只有被override instance method會依照object真實型別去動態的選擇呼叫的method,static methods和variable變數都不會。
- object reference 決定了在執行時期要使用哪一個overriding method。在compile時期,由reference variable決定了要使用哪一個overloading method。
結論:polymorphism只能適用於instance method!!
- object reference 決定了在執行時期要使用哪一個overriding method。在compile時期,由reference variable決定了要使用哪一個overloading method。
結論:polymorphism只能適用於instance method!!
沒有留言:
張貼留言