---
# System prepended metadata

title: 繼承與多重

---

# 繼承與多重
## 繼承: 為了重提高程式的重複利用性，子類別可使用父類別之屬性與方法
1. 在於子類別名稱後加上extends 父類別名，如:
public  class  Notebook extends Product

2. 子類別可直接使用父類別之屬性與方法，但方法必須寫super.方法名稱，如
super.desc();
3. 子類別除了新增自己的屬性及方法，也可「Override(覆寫)」父類別的方法，重新進行改寫，但☆方法名稱'參數類型及個數都必須完全相同☆
4. 子類別產生物件時(new)，子類別的建構方法一開始(第一行)必須呼叫父類別的建構方法，寫法為this()，注意!!不是一般方法所以沒有.，另外建議父類別建構方法必須留一個空的建構方法，避免子類別呼叫不到，如:
```
//父類別
public  class Product {

	//空的建構方法
	public Product() {
		
	}
	
	//建構方法
	public Product(String name, int price) {
		this.name = name;
		this.price = price;
	}
    }
 //子類別   
    public  class  Notebook extends Product{

	public int  warranty;
		
	//建構方法
	public Notebook(String name,int price , int warranty) {
		super(name,price);//可以透過super()呼叫父類別「建構方法」，但必須在第一行
		this.warranty = warranty;
	
	     }
    }
    
```
5. 快速產生建構方法: source>Generate Constructor using Fields
    

## 多型:藉由繼承，一個物件可以使用多個型態來表示或操作






1. 透過父類別型別來操作子類別的方法(也就是利用父類別型態達到相容所有子類別只需要一個方法)
2. 即便有新的子類別，也不必修改程式碼

舉例:
Food與Notebook都繼承Product，因此父類別只需要開設一個方法，如desc，
並且在Food與Notebook都進行覆寫，進行各自所需呈現的內容。
最後主程式只需要new Food與Notebook兩種物件，並且用陣列宣告父類別型別，將其都裝進去，如此呼叫desc方法時都會以各自子類別方法進行。

```
public class TestProduct {
public static void main(String[] args) {
Notebook nb = new Notebook("Acer",20000,365);//產生Notebook類別的物件
Food food = new Food("肉鬆",160,expireDate);//產生Food類別的物件
Product[] items= {nb,food};//用陣列來裝不同商品，並且類別為父類別
buy(items);//呼叫buy方法
    }
 
 
 public static void buy(Product[] prods) {//用父類別Product的型態
		int sum=0;
		for(Product p : prods) { //左變數，右陣列
		System.out.println("買入:"+p.desc());
		sum=sum+ p.getPrice();
		}
		System.out.println("買入金額="+sum);
	}  

    
}

```

3. 當需要將父類別強制轉子類別時，通常會以 instanceof 來判別物件是否具備某型態，並再將其作強制轉換，如
```
if(item instanceof Notebook{
Notebook nb1= (Notebook)item;//強制轉為Notebook型別
System.out.println("保固="+nb1.getWarranty());
})
//原本item為Product型別
```

![](https://i.imgur.com/L392kxS.png)
![](https://i.imgur.com/if8OzTc.png)
4. 通常設計時，都會將父類別設定abstract，並開方法規格，但不實作方法，由子類別繼承後覆寫

```
public  abstract class Animal {//父類別 :動物

	private String name;

	public Animal(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	//動物會talk
	public abstract   void talk();
	
	//動物會吃
	public  abstract void eat() ;
	
}

-------------------------------------------------------
public class Dog  extends Animal{//子類別 :狗

	public Dog(String name) {
		super(name);
		
	}

	@Override
	public void talk() {
		System.out.println("汪汪");
	}

	@Override
	public void eat() {
		System.out.println("狗吃飯");
	}

}

-------------------------------------------------------
public class Cat extends Animal { //子類別 :貓

	public Cat(String name) {
		super(name);
		// TODO Auto-generated constructor stub
	}

	@Override
	public void talk() {
		System.out.println("喵喵");
	}

	@Override
	public void eat() {
		System.out.println("吃飯");
	}
	
	public void scratch() {
		System.out.println("抓抓");
	}

}

-------------------------------------------------------主程式

public class TestAnimal {

	public static void main(String[] args) {

		Animal[] animals= new Animal[] {new Cat("貓"),new Dog("狗")};
		
	
		for(Animal a:animals ) {//for(左變數，右陣列 ){
			
			
			System.out.print(a.getName()+":" );
			a.talk();
			if(a instanceof Cat) {
				((Cat) a).scratch();
			}
		}
	}

}

```
