在 C# 中,可以透過繼承來定義類別階層,讓衍生類別(Car)繼承父類別(Vehicle)的行為和資料。如果沒有指定父類別,類別會繼承object類別。
父類別可以透過三種方式提供功能給衍生類別:
virtual方法,它就像一般方法,但衍生類別可以改變它。abstract方法,這是一種沒有實作的方法,衍生類別必須實作它。含有abstract方法的類別也必須標記為abstract。抽象類別無法具現化。protected存取修飾詞允許在衍生類別中存取父類別的成員,但會阻擋其他類別存取。
衍生類別可以透過base關鍵字存取父類別的成員。
// Inherits from the 'object' class
abstract class Vehicle
{
// Can be overridden
public virtual void Drive()
{
}
// Must be overridden
protected abstract int Speed();
}
class Car : Vehicle
{
public override void Drive()
{
// Override virtual method
// Call parent implementation
base.Drive();
}
protected override int Speed()
{
// Implement abstract method
}
}
衍生類別的建構函式在執行自己的建構函式邏輯之前,會自動呼叫父類別的建構函式。可以使用base關鍵字將引數傳遞給父類別的建構函式:
abstract class Vehicle
{
protected Vehicle(int wheels)
{
Console.WriteLine("Called first");
}
}
class Car : Vehicle
{
public Car() : base(4)
{
Console.WriteLine("Called second");
}
}
當一個基底類別衍生出多個類別時,這兩個(或更多)類別通常會以不同方式實作基底類別的某個方法。這是一個非常重要的原則,稱為多型。舉例來說,下面這個改編自上例的範例展示了使用Vehicle的程式碼如何根據具現化的載具型別來改變行為。
abstract class Vehicle
{
public abstract string GetDescription();
}
class Car : Vehicle
{
public Car()
{
}
public override string GetDescription()
{
return "Runabout";
}
}
class Rig : Vehicle
{
public Rig()
{
}
public override string GetDescription()
{
return "Big Rig";
}
}
Vehicle v1 = new Car();
Vehicle v2 = new Rig();
v1.GetDescription();
// => Runabout
v2.GetDescription();
// => Big Rig
在這道練習中,你會玩一款叫做「Wizard and Warriors」的角色扮演遊戲,可以選擇扮演巫師或戰士。
戰士和巫師各有不同的規則來決定他們造成的傷害點數。
戰士的規則如下:
巫師的規則如下:
一般來說,角色永遠不會處於易受傷狀態。不過,巫師如果沒有準備法術,就_會_處於易受傷狀態。
你有六個任務要處理戰士和巫師角色。
覆寫Character類別上的ToString()方法,回傳角色的描述,格式為"Character is a <CHARACTER_TYPE>"。
var warrior = new Warrior();
warrior.ToString();
// => "Character is a Warrior"
確保Character.Vulnerable()方法永遠回傳false。
var warrior = new Warrior();
warrior.Vulnerable();
// => false
實作Wizard.PrepareSpell()方法,讓巫師能事先準備法術。
var wizard = new Wizard();
wizard.PrepareSpell();
確保巫師沒有準備法術時,Vulnerable()方法回傳true;否則回傳false。
var wizard = new Wizard();
wizard.Vulnerable();
// => true
實作Wizard.DamagePoints()方法,回傳造成的傷害點數:已準備法術時為 12 點傷害,未準備時為 3 點傷害。
var wizard = new Wizard();
var warrior = new Warrior();
wizard.PrepareSpell();
wizard.DamagePoints(warrior);
// => 12
實作Warrior.DamagePoints()方法,回傳造成的傷害點數:目標處於易受傷狀態時為 10 點傷害,否則為 6 點傷害。
var warrior = new Warrior();
var wizard = new Wizard();
warrior.DamagePoints(wizard);
// => 10