## 多載 > 多載指的就是可以有很多個同樣名字的方法,各自去接不同的參數。 ``` 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/)