天天看點

java核心技術學習筆記7---繼承與多态

多态是OOP繼抽象、封裝、繼承後的又一基本特性。我們把在Java中的多态性概括到方法多态上。而這種方法的多态性又分為編譯時多态(編譯期綁定、前期綁定、靜态綁定)和運作時多态(運作時綁定、後期綁定、動态綁定)。

編譯時多态

編譯期多态主要展現在類的重載。

 在一個類中聲明多個同名方法,但方法的參數清單不同。稱為方法重載。

方法重載不分執行個體方法還是靜态方法。也就是說,一個執行個體方法的名稱及參數清單與本類中一個靜态方法的名稱及參數清單一樣是不可以的。在聲明方法時,重載多态性是看不出來的。隻有在調用時,你才會感覺象是一個方法有不同的形态(可以使用不同的參數調用)。其實我們聲明了多個方法。編譯器差別方法的方式是方法名稱及參數清單,而不隻是方法名稱。

所謂綁定就是将一個方法調用與一個方法主體(方法聲明的方法體)聯系起來。而編譯期綁定是在編譯期就可以決定下來的綁定。那就是方法重載。編譯器可以把方法調用處标記為“調用符号為XXX的方法”的位元組碼,而在方法聲明處标記為“符号為XXX的方法”。這時已經完成了綁定動作。

運作時多态

運作時多态主要展現在繼承中子類對父類方法的重寫(覆寫)上。

方法覆寫的特性與方法重載不同,覆寫是指,在子類中重寫父類中已有的執行個體方法。

覆寫的文法要求:

1) 父類中已有方法。

2)父類中使用private、static或final修飾的方法不能覆寫。就算你在子類中重寫了以上方法也不會真的産生覆寫效果。

3) 覆寫方法要求方法的傳回值類型、方法名稱、方法參數清單必須于父類中被覆寫方法相同。

4) 覆寫方法要求通路級别隻能更寬松,而不能更嚴格。例如父類方法的通路級别為protected,那麼子類方法隻能是protected或public,而不能是預設或private。

5) 覆寫方法要求聲明的異常隻能等于或少于父類方法聲明的異常。

編譯器調用方法過程

1)編譯器檢視對象的聲明類型和方法名。假設調用x.f(Param),且x被聲明為C類的對象。編譯器會一一列舉所有C類中名為f的所有方法和其超類中通路屬性為public且名為f的方法。

2)得到所有候選方法後,編譯器将檢視調用方法時提供的參數類型。如果在所有方法名為f的方法中存在一個參數類型與提供的參數完全比對,則直接調用該方法,這個過程被稱為“重載解析”(overloading resolution),若沒找到與參數類型比對的方法,或者發現經過類型轉換後有多個方法與之比對,則報錯。

3)如果方法是private,static ,final或者構造器,那麼編譯器可以準确的指導應該調用哪個方法,這種方式稱為“靜态綁定”(static binding)。

4)若調用方法依賴于隐式參數的實際類型,采用動态綁定方式調用方法,虛拟機一定調用與x所引用的對象的實際類型最合适的那個方法。若x的實際類型為D類,它是C類的子類。如果D類定義了方法f(Stirng),就調用它,否則,再在D類的父類中尋找方法f(String)以此類推。