C# - Override 覆寫

讓你改寫繼承到的行為

  • 在原本被改寫的 method 前加上 virtual
  • 在改寫的 methods 加上 override
  • override 的 method 其名稱與參數型別都要跟被 overrid
1
2
3
4
5
6
7
8
9
10
//要覆寫的基底類別

class Creature
{
public string name;
public virtual string attack(Creature target)
{
return name + "攻擊了" + target.name;
}
}

繼承基底類別原有的行為,但是使用 override 改寫內容

1
2
3
4
5
6
7
8
9
10
11
12
class Villager:Creature
{
public Villager(string name)
{
this.name = name;
}

public override string attack(Creature target)
{
return name + "不能攻擊其他人";
}
}

問題:
寫新的 method 也能做到想覆寫的新行為

1
2
3
4
5
6
7
8
9
//要覆寫的基底類別
class Creature
{
public string name;
public virtual string attack(Creature target)
{
return name + "攻擊了" + target.name;
}
}

像這樣

1
2
3
4
5
6
7
8
9
10
11
class Monster:Creature
{
public Monster(String name)
{
this.name = name;
}
public string move2()
{
return name + "橫著走";
}
}
1
2
3
4
5
6
7
8
9
private void button1_Click(object sender, EventArgs e)
{
Player p = new Player("阿勇");
Monster m = new Monster("Slim");
Villager v = new Villager("歐比屎");
string message = m.move2();
MessageBox.Show(message);

}

那為什麼需要 override? 使用 override 的好處是即使不用衍生類別呼叫新的 method 行為而用基底類別的身分呼叫新的 method 行為,也能呼叫到。

可以使用 Base Class 的變數存取繼承 class 的物件

1
2
3
4
5
6
7
8
9
10
private void button1_Click(object sender, EventArgs e)
{
Player p = new Player("阿勇");
Monster m = new Monster("Slim");
Villager v = new Villager("歐比");
Creature c = m;
string message = c.move();
MessageBox.Show(message);

}

雖然以新寫新 method 也能做到想覆寫的新行為,但只能在原有的變數底下呼叫

1
2
Monster m = new Monster("Slim");
string message = m.move2();

沒有使用 override 就不能以 base class 的身分呼叫

1
2
3
4
public string move2()
{
return name + "橫著走";
}

Override & Method Hiding

  1. 當繼承的類別之中有著與基底類別 (父類別) 名稱和參數相同的 method,但沒有加上 override 的字樣,就會觸發 method hiding (方法遮蔽) 的機制。
1
2
3
4
5
6
private void button1_Click(object sender, EventArgs e)
{
Fruit f = new Apple();

MessageBox.Show(f.saySomething());
}
1
2
3
4
5
6
7
8
class Fruit
{
public virtual string saySomething()
{
return "我是一個水果";
}

}
1
2
3
4
5
6
7
8
class Apple:Fruit
{
public string saySomething() // 沒有override 關鍵字
{
return "我是一個ringo";
}

}
  1. Method hiding (方法遮蔽) 指的是繼承的類別將原本基底類別的 method 隱藏起來了,但是與 override 不同,新的 method 會與舊的 method 共存,而且都可以被呼叫得到。

  2. 如果想要呼叫到被隱藏起來的 method,就必須要用該 method 所屬的 class 變數來呼叫。舉例說 class Orange 遮蔽了 class Fruit 裡面的 saySomething。如果想要呼叫到 class Orange 物件中繼承到原本 A 版本的 saySomething ,就要用 Fruit 型別的變數去存取 Orange 的物件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 private void button1_Click(object sender, EventArgs e)
{
//Orange o = new Orange();
Fruit o = new Orange(); // 用fruit 型別的變數去存取 Orange 的物件
MessageBox.Show(o.saySomething());
}

// 衍生類別
class Orange:Fruit
{
public string saySomething()
{
return "我是一個煩人柳丁";
}

}

// 基底類別

class Fruit
{
public virtual string saySomething()
{
return "我是一個水果";
}

}
  1. 加上 new 關鍵字使用方法遮蔽
    為了防止跟 override 混淆,想要使用方法遮蔽時可以在 method 前面加上「new」來加以區分。
1
2
3
4
5
6
7
8
class Orange:Fruit
{
public string saySomething()
{
return "我是一個煩人柳丁";
}

}

Powered by Hexo and Hexo-theme-hiker

Copyright © 2013 - 2020 CYC'S BLOG All Rights Reserved.

UV : | PV :