學習軌道
/
C#
C#
/
練習
/
巫師與戰士
巫師與戰士

巫師與戰士

學習練習

簡介

繼承

在 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」的角色扮演遊戲,可以選擇扮演巫師或戰士。

戰士和巫師各有不同的規則來決定他們造成的傷害點數。

戰士的規則如下:

  • 若攻擊的目標並非處於易受傷狀態,造成 6 點傷害
  • 若攻擊的目標處於易受傷狀態,造成 10 點傷害

巫師的規則如下:

  • 若巫師事先準備了法術,造成 12 點傷害
  • 若巫師沒有事先準備法術,造成 3 點傷害

一般來說,角色永遠不會處於易受傷狀態。不過,巫師如果沒有準備法術,就_會_處於易受傷狀態。

你有六個任務要處理戰士和巫師角色。

1. 描述角色

覆寫Character類別上的ToString()方法,回傳角色的描述,格式為"Character is a <CHARACTER_TYPE>"。

var warrior = new Warrior();
warrior.ToString();
// => "Character is a Warrior"

2. 讓角色預設不易受傷

確保Character.Vulnerable()方法永遠回傳false。

var warrior = new Warrior();
warrior.Vulnerable();
// => false

3. 讓巫師可以準備法術

實作Wizard.PrepareSpell()方法,讓巫師能事先準備法術。

var wizard = new Wizard();
wizard.PrepareSpell();

4. 讓巫師在未準備法術時處於易受傷狀態

確保巫師沒有準備法術時,Vulnerable()方法回傳true;否則回傳false。

var wizard = new Wizard();
wizard.Vulnerable();
// => true

5. 計算巫師的傷害點數

實作Wizard.DamagePoints()方法,回傳造成的傷害點數:已準備法術時為 12 點傷害,未準備時為 3 點傷害。

var wizard = new Wizard();
var warrior = new Warrior();

wizard.PrepareSpell();
wizard.DamagePoints(warrior);
// => 12

6. 計算戰士的傷害點數

實作Warrior.DamagePoints()方法,回傳造成的傷害點數:目標處於易受傷狀態時為 10 點傷害,否則為 6 點傷害。

var warrior = new Warrior();
var wizard = new Wizard();

warrior.DamagePoints(wizard);
// => 10
透過 GitHub 編輯 連結會在新視窗或分頁中開啟
C# Exercism

準備好開始 巫師與戰士 了嗎?

註冊 Exercism,透過 62 個概念178 個練習 和真人引導來學習並精通 C#,全部免費。