Day32 ウォームアップ(10分)【ポリモーフィズム②:interface】

広告

第2部:Unity に入る前の準備(Day31〜Day32)

※10分の使い方は、「進め方(10分の使い方)」を参照
※生成AIは使いません
※全部できなくてOK
※今日のゴール目安:提出A(問題1が動く)で合格、提出B(1・2)で標準到達、提出C+発展で上位到達


今日の準備(ウォームアップの前に)

  1. Day32.cs を追加する(ソリューションエクスプローラーで、プロジェクト「MiniPractice」を右クリック → 追加 → クラス → 名前を Day32.cs
  2. Program.cs を開き、Main 内の Day31.Run() を Day32.Run() に書き換える

最初に:今日のクラスの形を確認

今日は interface(インターフェース) を使います。React() というメソッドを持つ」という約束だけを IReact に書き、中身の違うクラスDoor / Switch / Chest)が それぞれ別の文字列を返すようにします。基底クラスはなくても同じ IReact 型で変数や配列にまとめられます。

今日は LINQ は使いませんfor / foreach のまま進めます)。

internal class Day32
{
    interface IReact
    {
        string React();
    }

    class Door : IReact
    {
        public string React()
        {
            return "[Door open]";
        }
    }

    class Switch : IReact
    {
        public string React()
        {
            return "[Switch flip]";
        }
    }

    class Chest : IReact
    {
        public string React()
        {
            return "[Chest open]";
        }
    }

    public static void Run()
    {
        // ここに書く
    }
}
  • IReact 型の変数に new Door() を入れても、React() は [Door open] になります(実装クラスに応じて返る文字列が変わる)
  • Day33 以降で出す Enemy や TakeDamage とは 別の名前にしてあります(Unity 橋渡しで新しく学ぶときと混ざりにくくするため)

🔹 出力について(教材共通)

教材では 簡潔な出力例を載せています。条件・数え方・集約が正しければ、ラベル付きで出しても構いません。


🔹 Day31 の振り返り(1分)

  • virtual / override … 基底型の変数から Tag() を呼ぶと、派生側の中身が使われました
  • 今日のポイント継承なしでも interface で 「同じメソッド名を持つ」約束を切り、別名のクラスを IReact[] などでまとめられます

🔹 今日のポイント

やりたいこと
インターフェース型の変数に実装を入れるIReact r = new Door();
同じ型でまとめて呼ぶConsole.WriteLine(r.React());
配列に混ぜるIReact[] items = { new Door(), new Switch(), new Chest() };

進め方(10分の使い方)

  • 最初の5分:自分の力だけで書いてみましょう。
  • 後半5分:過去の自分のコード・教材を見てOKです。

1限の過ごし方(目安)

時間(目安)内容
0〜15分ウォームアップ
15〜45分学習時間(Slack・スライド・口頭の指示を最優先)
45〜50分振り返りなど
  • 提出が終わったら … Commit/Push と Slack「Day32 完了」は提出ルールに従います。

提出ルール(重要)

  • 提出A:問題1だけ / 提出B:問題1・2 / 提出C:問題1・2・3(+発展)
  • Slack:「Day32 完了しました」

■ 問題1(基礎)

Run() の中で次を書いてください。

  1. IReact 型の変数 r に new Door() を代入する
  2. Console.WriteLine(r.React()); を 1回呼ぶ
  • 教材の目安の出力:[Door open]1行

■ 問題2(条件)

次の items 配列を Run() の中に用意し、foreach (IReact x in items) で React() の戻り値を表示してください(1行に1つの文字列)。

IReact[] items =
{
    new Door(),
    new Switch(),
    new Chest(),
};
  • 教材の目安:[Door open] / [Switch flip] / [Chest open] の 3行

■ 問題3(集計)

同じ items 配列について、React() が返す文字列に "open" を含む IReact が 何個かを数え、個数だけを1行で表示してください。

  • ヒント:React() は 文字列です。"open" を含むかは Contains で調べられます
  • 教材のデータでは [Door open] と [Chest open] の 2個[Switch flip] は含みません)なので、出力は 2

■ 発展A(余裕がある人)

次の items2 配列を用意してください。

IReact[] items2 =
{
    new Door(),
    new Switch(),
    new Chest(),
    new Switch(),
};

React() の文字列の長さが 12 以上のものだけを List<IReact> に追加し、つぎの 順序どおりに表示してください。

  1. 追加した各要素の React() の戻り値を 1行ずつ
  2. 追加した要素の React() の文字列長の合計を 1行
  3. React() の文字列長の平均を 1行整数割り算でよい → 合計 / list.Count
  4. 最大の長さを 1行
  5. 最小の長さを 1行

目安React() の戻り値の長さ.Length[ と ] も1文字ずつ数える)が 12 以上なのは、"[Switch flip]"(13文字) が 2件(配列の2体目と4体目の Switch)と、"[Chest open]"(12文字) が 1件で、List には計3要素が入ります。表示は [Switch flip] → [Chest open] → [Switch flip] の3行。文字数の合計 38、平均 12(整数割り算)、最大 13、最小 12


■ 発展B(発展Aが動いたらチャレンジ)

Run の外に private static bool IsChestReact(IReact r) を 1つ定義してください。

  • r.React() が "Chest" という部分文字列を含むとき trueContains で判定)

items2 を foreach で回しIsChestReact(x) が true になる要素(x はループ変数で、問題2と同じでよい)の React() の戻り値を1行ずつ表示してください。

  • 教材の目安:[Chest open] の 1行
// 呼び出しのイメージ
foreach (IReact x in items2)
{
    if (IsChestReact(x))
    {
        Console.WriteLine(x.React());
    }
}

⚠️ つまずきやすい点

  • IReact r = new IReact(); … interface 自体は new できませんnew Door() など 実装クラスを使います
  • Contains("open") … [Switch flip] 全体には open という並びが無いので、問題3の集計に入りません([Door open] と [Chest open] には入ります)

🎯 今日の目的

  • 別名のクラスが 同じ interface 型で配列にまとまり、同じ React() 呼び出しで返る文字列が変わることを体感する(Unity の IDamageable のような共通操作の入口)

次へ

Day33 から Unity 橋渡しに入り、EnemyHpTakeDamage など)を コンソールのまま扱います。講師・Slack の指示に従って進めてください。

訪問数 50 回, 今日の訪問数 50回

広告

C#

Posted by hidepon