繼承(extends)
好處是減少代碼冗余、增加覆用性、便於功能的擴展、多態性。子類繼承父類後,子類會獲取父類的結構、屬性、方法,如果為 private
,因為封裝性影響,子類不能直接調用父類結構,需透過 getter 和 setter 進行操作。
子類繼承之後可以聲名自己持有的屬性和方法,實現功能擴展。在 JAVA 只支持單繼承和多層繼承,無多重繼承。一個類能被多個子類繼承,一個類只能有一個父類。
所有 java 類(除 java.lang.Object)直接會間接繼承 java.lang.Object 類
覆寫 (override)
- 回傳類型、方法名和參數個數需一致
- 回傳類型可以是該類型的子類
- 同名同參數方法要是非 static 實現重寫,否則為非重寫
- 子類重寫的方法權限修飾不小於父類被重寫的方法的權限
- 子類拋出的異常範圍不能大於父類
以繼承來說 B 繼承 A,只要 B 有覆寫 A 的相關方法,則建立物件時取得的是 B 的覆寫,否則就是 A 的。
super
用來調用以下
屬性
法
建構方法
在子類的方法或建構方法中,透過使用
super.屬性
或super.方法
的方式,顯示的調用父類中聲明的屬性或方法,通常都省略當子類和父類中定義同名屬性時,要從子類調用父類的屬性,則必須使用
super.屬性
或super.方法
在建構方法中使用
super(參數列表)
需再首行
無聲明
this()
、super()
,默認使用父類別中空參的建構方法與
this
不能同時使用。為何不能與this
出現在同一個建構方法 ?(因為要寫在首行) 為何只能在第一句出現 ?(初始化)
子類物件實例化過程
假設 D 繼承 C,C 繼承 B,B 繼承 A。在建立物件 D 時在堆中會將一連串的類別進行載入,就是加載父類中聲明的屬性。這過程中我們會直接或間接調用父類的建構方法,直到 Object
類為止。
多態性 (Polymorphism)
物件的多態性,父類的引用指向子類的物件,會應用於抽象類(Abstract)或介面(interface)上。在 JAVA 中引用變數有兩個類型非分別是編譯時類型
、運行時類型
,若兩者類型不一致則會出現多態。
- 父類的引用指向子類的對象
- 當調用父子類同名同參數方法時,實際執行的是子類重寫父類的方法(虛擬方法調用)
- 編譯時只能調用父類聲名的方法,但在運行期,實際是子類重寫父類的方法(編譯看左邊,運行看右邊)
- 多態的前提
- 類的繼承關係
- 方法的重寫
- 物件的多態性,適用於方法,不適用於屬性
- 因此屬性調用時以左邊為主
- 屬於運行時行為
- 因為不明確結果
- 對於
重載
而言,在方法調用之前,編譯器就已經確定了所要調用的方法,這稱為靜態綁定
;對於多態而言,只有等到方法調用的那一刻,編譯器才會確定所要調用的具體方法,這稱為動態綁定
- 多態性更是解決重載的副作用
interface
、Abstract
肯定體現多態性
class Animal {
public void a(){
}
public void b(){
}
}
class Dog extends Animal{
public void a(){
}
public void b(){
}
}
class Cat extends Animal{
public void a(){
}
public void b(){
}
}
// 調用時
public class Test {
public static void main(String [] args){
Test t = new Test();
t.fun(new Dog());
t.fun(new Cat());
}
public void fun(Animal animal){
animal.a();
animal.b();
}
}