---
# System prepended metadata

title: CH10-繼承與多型(2020/06/22)

---

<style>
img{border:1px solid gray;}

#sp{color:#CC0000;}

#imp{color:#CC0000; 
    font-style:bold; 
    background-color:#FFFFBB;}
    
#imp2{color:#5500FF; 
    font-style:bold; 
    background-color:#FFFFBB;}
    
#tit{color:white; 
    font-style:bold; 
    
</style>

# CH10-繼承與多型(2020/06/22)

+ 子類別依父類別再繼續擴充
    <img src="https://i.imgur.com/kyO2HhT.png">
+ 一個類別可以繼承它的父類別所有狀態及行為，我們即把此稱之為子類別(subclass)延伸(extends)自父類別(superclass)
+ 子類別將會繼承到父類別中所有可以存取的成員，包括變數與方法
+ 子類別繼承父類別功能之後：
    + 還可以再加入新方法(method)
    + 可以覆寫(override)從父類別而來的方法，建立一個專屬自己類別的運作邏輯
    + 語法：class SubClassName <font id="imp">extends</font> SuperClassName

## 覆寫(override)
+ 子類別繼承父類別後，不滿意父類別定義的方法，子類別可以在繼承後重新改寫，即為 overriding
+ 須滿足以下條件才算覆寫成功，但其實只需把握【<font id="sp">只對方法內容作改變，所以基本上方法的結構一樣即可</font>】的原則
    + <font id="imp">方法名稱</font>與父類別相同
    + <font id="imp">參數個數</font>與父類別相同
    + <font id="imp">參數型別</font>與父類別相同
    + <font id="imp">回傳值</font>與父類別相同
        + JDK 1.5 開始，如回傳型態是類別，則可以是原方法回傳值型別的子類別
    + <font id="imp">存取修飾子</font>的等級<font id="sp">不可小於</font>原方法
    + 子類別覆寫父類別定義有throws的方法時，不得比父類別被覆寫方法的Exception還要高階（完全沒有throws時是最低階的，此時若override則不可throws任何exception）
    + final
        + 一個<font id="sp">類別</font>宣告為final，表示這個類別不能被繼承
        + 一個<font id="sp">方法</font>宣告為final，表示這個方法不能被覆寫(override)
        + 一個<font id="sp">變數</font>宣告為 final，表示這個變數在初始值化後，不得再變更其值，也就是常數(Constant);如果一個變數加上final，就一定要在宣告時給值。
        + 一個<font id="sp">物件參考變數</font>宣告為final ，表示這個變數在初始值化後，不得再指向另一個物件(表儲存的記憶體位址不能改變，也就是永遠使用同一個物件實體)
    + static
        + static 方法不可被覆寫為非 static 方法

## super()
+ 子類別透過<font id="imp">super.</font>可以呼叫上一層類別的方法(僅能呼叫上一層，無法呼叫上上上層)
+ 子類別透過建構子，用<font id="imp">super(…)</font>將共同的建構子參數傳給父類別
    + 物件產生時，建構子呼叫的順序為先父類別再子類別，所以：
        + 建構子中若有出現 super(…)，一定要放在第一個敘述位置
        + 建構子中若未出現 super(…)，Java預設會有一個隱形的 super() 
        【呼叫父類別不帶參數的建構子】預設自動放在第一個敘述的位置
        super(...)跟this(...)在建構子內都得放在第一個位置以符合執行的順序規則，所以兩者只能<font id="imp">擇一</font>使用。
    + 要使用父類別方法時最好加上super，否則會先找到子類內同名的方法
```ava=1

public class WithSuper {

	public void print() {
		System.out.println("我是父類別");
	}
		
}


/* [案例1]本身有method run()，會印出：
　我是子類別
　我是父類別*/
public class WithoutSuper extends WithSuper{

	public void print() {
		System.out.println("我是子類別");
	}
	
	public void run() {
		print();
		super.print();
	}
	
	public static void main(String[] args) {	
		WithoutSuper withoutSuper = new WithoutSuper();
		withoutSuper.run();
	}

}

/*[案例2]本身無method run()，會印出：
　我是父類別
　我是父類別*/
public class WithoutSuper extends WithSuper{
	
	public void run() {
		print();
		super.print();
	}
	
	public static void main(String[] args) {	
		WithoutSuper withoutSuper = new WithoutSuper();
		withoutSuper.run();
	}

}

```