---
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)