## 多載
> 多載指的就是可以有很多個同樣名字的方法,各自去接不同的參數。
```
public class Card
{
public Card (string name, int attack, int health)
{
this.Name = name;
this.Attack = attack;
this.Health = health;
}
public Card (string name)
{
this.Name = name;
this.Attack = this.Level;
this.Health = this.Level;
}
public Card ()
{
this.Name = "Noname";
this.Attack = this.Level;
this.Health = this.Level;
}
}
```
### 建構式鏈接
> 如果規則或是建立的步驟一致的話,為了能夠把規則集中到一個地方方便修改,並且減少多餘的程式碼。我們通常會試著讓其他的建構式去呼叫主要的建構式
```
public Card (string name, int attack, int health)
{
this.Name = name;
this.Attack = attack;
this.Health = health;
}
// 會呼叫上面那個建構式
public Card (string name) : this(name: name, attack: 5, health: 5)
{
// 呼叫完 Card(name, attack, health) 之後做的事
}
// 會呼叫上面那一個建構式
public Card () : this(name: "Noname")
{
// 呼叫完 Card(name) 之後做的事
}
```
## 存取範圍與存取子
| Public | Private | Protected |
| -------- | -------- | --------
| 所有人| 只有自己(同一個Class內) | 自己和繼承者
| internal | Protected internal |
| -------- | -------- |
| 同組件(dll)| 自己和繼承者或是同個組件 |
## 繼承
> **繼承是一種「is-a」的關係。**
> 舉例來說,狗跟貓都是哺乳類,因此他們都可以繼承到一些哺乳類共通的特徵(例如哺乳、用肺呼吸)
> 藉由繼承,我們可以把這些哺乳類共有的特徵全部放在哺乳類這個物件,再由狗和貓分別去繼承哺乳類,藉此讓他們都能得到哺乳類的特徵
```
// 基礎類別(共同類別)
public class Card
{
public int Cost;
private string _description;
public string Description { /* set; get; */}
}
// 怪獸卡
public class MonsterCard : Card
{
public string Name;
public int Attack;
public int Health;
}
// 魔法卡
public class MagicCard : Card
{
public int Cost;
public int Effect;
}
```
建立MonsterCard類別
```
var warrior = new MonsterCard(name: "戰士", attack: 4, health: 3);
warrior.Description = "他是一個專殺哥布林的戰士!";
var fireball = new MagicCard(cost: 10, effect: 4);
fireball.Description = "這是一張火球魔法卡";
(Description 是 Card基礎類別中定義的,因為繼承Card所以擁有此參數)
```
## 多型
> **一樣的事,不同做法。**
> 例如:一樣的紅茶不同飲料店不同的配方
```
// 定義行為
public class BeverageShop
{
public virtual string BlackTea()
{
}
public virtual string GreenTea()
{
}
public virtual string OolongTea()
{
}
}
// 繼承者各自實作
// A 飲料店
public class MilkShop : BeverageShop
{
public override string BlackTea()
{
return "紅茶茶葉30g + 水200cc";
}
public override string GreenTea()
{
return "綠茶茶葉30g + 水200cc";
}
public override string MilkTea()
{
return "紅茶茶葉30g + 牛奶 100cc + 水200cc";
}
}
// B 飲料店
public class BubbleTeaShop : BeverageShop
{
public override string BlackTea()
{
return "紅茶茶葉40g + 水250cc";
}
public override string GreenTea()
{
return "綠茶茶葉40g + 水250cc";
}
public override string MilkTea()
{
return "紅茶茶葉45g + 牛奶 150cc + 水150cc";
}
}
```
建立類別
```
public void newProject()
{
BeverageShop aShop = new MilkShop();
BeverageShop bShop = new BubbleTeaShop();
aShop.BlackTea(); // "紅茶茶葉30g + 水200cc"
bShop.BlackTea(); // "紅茶茶葉40g + 水250cc"
}
```
## 抽象 (abstract)
> 本身不應該被實體化成一個物件,這種類別我們就應該把它們標記為抽象類別
```
// 加在方法上時,代表這個方法無法被叫用,只能由繼承者去重新定義這個方法。
abstract class Animal
{
public string color { get; set; }
public abstract void Eat();
}
```
## 覆寫 (override)
> 覆寫是指抽象方法的實作
```
public class Dog : Animal
{
public string color { get; set; } = "Black";
public override void Eat()
{
/* 嚼嚼嚼 */
}
}
```
## 虛擬 (virtual)
> 可以實作,同時也讓子類別可以覆寫。
```
public class Dog
{
public virtual void Eat()
{
/* 嚼嚼熱狗 */
}
}
public class Giwawa : Dog
{
/* 直接使用 Dog 類別的 Eat */
}
public class RobotDog : Dog
{
public override void Eat()
{
/* 嚼嚼汽油 */
}
}
// 使用new方法覆寫
public class CyberDog : Dog
{
public new void Eat()
{
/* 嚼嚼汽油 */
}
}
```
> override 和 new 的差別在於多型時轉型成父類別時的行為:
>
> override 會直接取代掉父類別的方法,即使轉型為父類別還是以子類別的實作為主
> new 則是會建立一個子類別專屬的方法,若轉型為父類別就會變回父類別的方法
> (若未指定預設為 new)
```
public class Dog
{
public virtual void Eat()
=> Console.WriteLine("吃了熱狗");
}
public class Labrador : Dog
{
public override void Eat()
=> Console.WriteLine("吃了超大熱狗");
}
public class RobotDog : Dog
{
public new void Eat()
=> Console.WriteLine("喝了超多汽油");
}
// Labrador => override
var lala = new Labrador();
lala.Eat(); // 吃了超大熱狗
((Dog)lala).Eat(); // 吃了超大熱狗
// ==============================
// RobotDog => new
var robot = new RobotDog();
robot.Eat(); // 喝了超多汽油
((Dog)robot).Eat(); // 吃了熱狗
```
## 介面 (Interface)
> 介面只需要先定義好該做的事,裡面怎麼做不需要管
> 只需要宣告要求的方法,不需要撰寫方法本體。
```
public interface IProgrammer
{
void WriteCSharp();
void WriteSQL();
void WriteVB();
}
```
必須實作介面定義的所有方法
```
public class Hua : IProgrammer
{
// Error: Hua 未實作 IProgrammer.WriteCSharp()
public void WriteSQL() { /* Work */ }
public void WriteVB() { /* Work */ }
}
```
資料來源:[伊果的沒人看筆記本](https://igouist.github.io/)