--- tags: 繼承, 多形, 擴充方法, C# --- <!-- 使用黑色主題 --> {%hackmd BkVfcTxlQ %} <!-- 決定 CSS 樣板 --> {%hackmd @aidan/inc_hackmd_css %} # <span class="TopTitle">C# 繼承與多形</span> ## <span class="Title">主題0. 什麼是 Object</span> #### <span class="SubTitle">Lab0-1 Value type 居然有 method</span> [執行程式](https://repl.it/join/qixhrwjv-aidanlu) ```C#= class Program { static void Main(string[] args) { int a_int = 0; float b_float = 0.0f; bool c_bool = false; Console.WriteLine(a_int.GetType()); Console.WriteLine(b_float.GetType()); Console.WriteLine(c_bool.GetType()); Console.WriteLine("請按任意鍵繼續(不要按電源鍵)"); //ლ(・´ェ`・ლ) Console.Read(); } } ``` #### <span class="SubTitle">Lab0-2 不想打那麼多字,擴充方法出場</span> [執行程式](https://repl.it/join/tqmllzdh-aidanlu) ```C#=+ public static class Log { public static void ToConsole(this Type type) { Console.WriteLine(type.ToString()); } } class Program { static void Main(string[] args) { int a_int = 0; float b_float = 0.0f; bool c_bool = false; a_int.GetType().ToConsole(); b_float.GetType().ToConsole(); c_bool.GetType().ToConsole(); Console.WriteLine("請按任意鍵繼續(不要按電源鍵)"); Console.Read(); } } ``` #### <span class="SubTitle">Lab0-3 Boxing[~[1]~](https://nwpie.blogspot.com/2017/04/5-boxing-unboxing.html)[~[2]~](https://dotblogs.com.tw/joysdw12/2013/08/06/asp-net-boxing-unboxing)[~[MSDN]~](https://docs.microsoft.com/zh-tw/dotnet/csharp/programming-guide/types/boxing-and-unboxing),猜看看以下會有幾個錯誤</span> [執行程式](https://repl.it/@mikehsieh1/Lab0-3#main.cs) ```C#=+ class Program { static void Main(string[] args) { int a_int = 0; float b_float = 0.0f; bool c_bool = false; a_int = c_bool; a_int = b_float; b_float = a_int; b_float = c_bool; c_bool = a_int; c_bool = b_float; } } ``` #### <span class="SubTitle">Lab0-4 Object 登場</span> [執行程式](https://repl.it/@mikehsieh1/Lab0-4#main.cs) ```C#=+ class Program { static void Main(string[] args) { int a_int = 0; float b_float = 0; bool c_bool = false; Object a_obj; Object b_obj; Object c_obj; a_obj = c_bool; a_obj = b_float; b_obj = a_int; b_obj = c_bool; c_obj = a_int; c_obj = b_float; Console.WriteLine("請按任意鍵繼續(不要按電源鍵)"); Console.Read(); } } ``` #### 補充資料:override VS virtual method **Object Class** ![](https://i.imgur.com/LYJroH0.png) **Boolean Class** ![](https://i.imgur.com/WHduUok.png) ## <span class="Title">主題1. 建立 Cat class</span> #### <span class="SubTitle">Lab1-1 沒有建構子</span> [執行程式](https://repl.it/@mikehsieh1/Lab1-1#main.cs) ```C#=+ class Cat { /// <summary> /// Field (欄位) /// </summary> public int shout_num; public String name; string kind; /// <summary> /// Property (屬性) /// </summary> public string Kind { get { return kind; } } /// <summary> /// Method (方法) /// </summary> /// <returns></returns> public String Shout() { String result = ""; for (int i = 0; i < shout_num; i++) { result += "meow~ "; } return "My name is " + name + ". " + result; } } ``` #### <span class="SubTitle">Lab1-2 無參的建構子</span> [執行程式](https://repl.it/@mikehsieh1/Lab1-2#main.cs) ```C#=+ class Cat { /// <summary> /// Field (欄位) /// </summary> public int shout_num; public String name; string kind; /// <summary> /// Property (屬性) /// </summary> public string Kind { get { return kind; } } /// <summary> /// Constructor (建構函式, 建構子) /// </summary> public Cat() { this.kind = "Cat"; this.shout_num = 3; this.name = "No-Name"; } /// <summary> /// Method (方法) /// </summary> /// <returns></returns> public String Shout() { String result = ""; for (int i = 0; i < shout_num; i++) { result += "meow~ "; } return "My name is " + name + ". " + result; } } ``` #### <span class="SubTitle">Lab1-3 有參數的建構子</span> [執行程式](https://repl.it/@mikehsieh1/Lab1-3#main.cs) ```C#=+ class Cat { /// <summary> /// Field (欄位) /// </summary> public int shout_num; public String name; string kind; /// <summary> /// Property (屬性) /// </summary> public string Kind { get { return kind; } } /// <summary> /// Constructor (建構函式, 建構子) /// </summary> public Cat() { this.kind = "Cat"; this.shout_num = 3; this.name = "No-Name"; } public Cat(String name, int shout_num) { this.kind = "Cat"; this.shout_num = shout_num; this.name = name; } /// <summary> /// Method (方法) /// </summary> /// <returns></returns> public String Shout() { String result = ""; for (int i = 0; i < shout_num; i++) { result += "meow~ "; } return "My name is " + name + ". " + result; } } ``` ## <span class="Title">主題2. 建立 Dog class</span> [執行程式](https://repl.it/@jacklouk/PrimaryFatalConfig#main.cs) #### <span class="SubTitle">Lab2-1 以下程式碼有錯,請試著修正</span> ```C#=+ class Dog { /// <summary> /// Field (欄位) /// </summary> public int shout_num; public String name; string kind; /// <summary> /// Property (屬性) /// </summary> public string Kind { get { return kind; } } /// <summary> /// Constructor (建構函式, 建構子) /// </summary> public Cat() { this.kind = "Cat"; this.shout_num = 3; this.name = "No-Name"; } public Cat(String name, int shout_num) { this.kind = "Cat"; this.shout_num = shout_num; this.name = name; } /// <summary> /// Method (方法) /// </summary> /// <returns></returns> public String Shout() { String result = ""; for (int i = 0; i < shout_num; i++) { result += "meow~ "; } return "My name is " + name + ". " + result; } } ``` :::spoiler 正確寫法 :::success ```C#=+ class Dog { /// <summary> /// Field (欄位) /// </summary> public int shout_num; public String name; string kind; /// <summary> /// Property (屬性) /// </summary> public string Kind { get { return kind; } } /// <summary> /// Constructor (建構函式, 建構子) /// </summary> public Dog() { this.kind = "Dog"; this.shout_num = 3; this.name = "No-Name"; } public Dog(String name, int shout_num) { this.kind = "Dog"; this.shout_num = shout_num; this.name = name; } /// <summary> /// Method (方法) /// </summary> /// <returns></returns> public String Shout() { String result = ""; for (int i = 0; i < shout_num; i++) { result += "Wong~ "; } return "My name is " + name + ". " + result; } } ::: ## <span class="Title">主題3. 建立 Animal class,讓 Cat, Dog 繼承自 Animal #### <span class="SubTitle">Lab3-1 以下程式碼有錯,請試著修正</span> (正確的程式碼可以參考[這裡](https://repl.it/@x94ej04hk4/PrevailingFlippantParentheses#main.cs)) **Animal Class** ```C#=+ class Animal { /// <summary> /// Field (欄位) /// </summary> public int shout_num; public String name; string kind; /// <summary> /// Property (屬性) /// </summary> public string Kind { get { return kind; } } public Animal() { this.name = "No-Name"; } public Animal(String name, int shout_num) { this.name = name; this.shout_num = shout_num; } } ``` **Cat Class** ```C#=+ class Cat : Animal { /// <summary> /// Constructor (建構函式, 建構子) /// </summary> public Cat() { this.kind = "Cat"; this.shout_num = 3; this.name = "No-Name"; } public Cat(String name, int shout_num) { this.kind = "Cat"; } /// <summary> /// Method (方法) /// </summary> /// <returns></returns> public String Shout() { String result = ""; for (int i = 0; i < shout_num; i++) { result += "meow~ "; } return "My name is " + name + ". " + result; } } ``` **Dog Class** ```C#=+ class Dog : Animal { /// <summary> /// Constructor (建構函式, 建構子) /// </summary> public Dog() { this.kind = "Dog"; } public Dog(String name, int shout_num) { this.kind = "Dog"; } /// <summary> /// Method (方法) /// </summary> /// <returns></returns> public String Shout() { String result = ""; for (int i = 0; i < shout_num; i++) { result += "Wong~ "; } return "My name is " + name + ". " + result; } } ``` ## <span class="Title">主題4. 為 String Class 新增擴充方法</span> [執行程式](https://repl.it/@ivanlee10/Added-String-class-extension-method-1#main.cs) ```C#=+ public static class Log { public static void ToConsole(this string msg) { Console.WriteLine(msg); } } ``` ## <span class="Title">主題5. 多型(Polymorphism)出場</span> #### <span class="SubTitle">Lab5-1 要同時讓100隻貓跟100隻狗都叫,而且所有貓狗的 name 都不能相同</span> 執行程式 * [Version 1](https://repl.it/@mikehsieh1/Question#main.cs) 小麥 * [Version 2](https://repl.it/@aidanlu/QuestionVer2) 使用 Array.Copy() * [Version 3](https://repl.it/@aidanlu/QuestionVer3) 使用 foreach * [Version 4](https://repl.it/@aidanlu/QuestionVer4) 使用 List<T> * [Version 5](https://repl.it/@jacklouk/QuestionVer5#main.cs) 大J * [Version 6](https://repl.it/@tonyliu13/KnownRareOffices#main.cs) Tony ### <span class="Question">:thinking_face: Q1. 當改變 Lab5-1 的貓狗數量面(例如改為5隻貓,11隻狗),那上面5種寫法,那1個是修改最多,而那一個是修改最少的?</span> * [Version 1](https://repl.it/@jacklouk/QuestionVer5-1#main.cs) 大J(繼承上題Ver5)