Chapter 07

第七章 条件に応じた class をインスタンス化させたい

kuramapommel
kuramapommel
2021.04.24に更新

それぞれの条件に応じた class

振る舞いのまとまりの作り方がわかったので、同じく LongSword classDualBlades class も実装してみましょう

// 太刀の振る舞いを凝集した LongSword class
class LongSword {
  public readonly name: string = "太刀"
  
  public attack(): void {
    console.log("太刀で攻撃")
  }
}

// 双剣の振る舞いを凝集した LongSword class
class DualBlades {
  public readonly name: string = "双剣"
  
  public attack(): void {
    console.log("双剣で攻撃")
  }
}

それぞれの 似た構造の異なるまとまり ができたので、あとは指定された WEAPON_TYPE をもとに該当するインスタンスを生成すれば良さそうですね

ここで重要になってくるのが という概念です
全てのデータには型があります

別々の class なので型が合わず、コンパイラに怒られる

型とは 「そのデータが持つ振る舞いをそのデータを扱いたい人に対して仕様としてわかるように明示的に示すため制約」 とここでは定義しておきましょう

つまり、「 Hoge という型は、 fuga というプロパティや、 doPiyo という振る舞いを持っている」というように仕様を外部に明示的に示しているものです

TypeScript のように弱い型付けの言語であれば、そこまで型を意識することなく実装することができますが、 JavaC# のように強い型付けの言語ではそうはいきません

下記は C# のコードですが コンパイルエラー になってしまいます

// これは C# のコードです

public sealed class Hello
{
    public static void Main()
    {
        var weapon = CreateWeaponInstance(WEAPON_TYPE.Bow);
        
        System.Console.WriteLine(weapon.Name);
    }
    
    // 引数で受け取った WEAPON_TYPE をもとに応じた武器のインスタンスを生成する関数
    // 戻りの型は複数選択できない
    private static Bow CreateWeaponInstance(WEAPON_TYPE weaponType)
    {
        switch (weaponType)
        {
            // LongSword 型を return しようとしているのでコンパイルエラー
            case WEAPON_TYPE.LongSword: return new LongSword();
            
            // DualBlades 型を return しようとしているのでコンパイルエラー
            case WEAPON_TYPE.DualBlades: return new DualBlades();
            
            case WEAPON_TYPE.Bow: return new Bow();
        }
        
        throw new ArgumentOutOfRangeException();
    }

    private sealed class LongSword
    {
        public string Name => "太刀";
    }
    
    
    private sealed class DualBlades
    {
        public string Name => "双剣";
    }
    
    
    private sealed class Bow
    {
        public string Name => "弓";
    }
    
    private enum WEAPON_TYPE
    {
        LongSword,
        DualBlades,
        Bow
    }
}

CreateWeaponInstance メソッドは Bow 型を return するように定義されているにもかかわらず、 LongSword 型や DualBlades 型を return しようとしているからですね

さて困りました
せっかく振る舞いをまとめた 3 つの class を用意したのに、これでは WEAPON_TYPE に応じてインスタンス化する class を切り替えることができません

ここでやっと出てきます、次章、ポリモーフィズムの要のひとつ interface の登場です