Day31 ウォームアップ(10分)【ポリモーフィズム①:virtual / override】

広告

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

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


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

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

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

今日は virtual(上書き可能) と override(上書き) を使います。基底クラス Unit に Tag() というメソッドを用意し、派生クラスで 表示内容を変えます。Unity の MonoBehaviour を継承して Update を書くことと、名前は違うが考え方は同じです。

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

internal class Day31
{
    class Unit
    {
        public virtual string Tag()
        {
            return "[Unit]";
        }
    }

    class Slime : Unit
    {
        public override string Tag()
        {
            return "[Slime]";
        }
    }

    class Boss : Unit
    {
        public override string Tag()
        {
            return "[Boss]";
        }
    }

    class Goblin : Unit
    {
        public override string Tag()
        {
            return "[Goblin]";
        }
    }

    public static void Run()
    {
        // ここに書く
    }
}
  • Unit 型の変数に new Slime() を入れても、Tag() は [Slime] になります(多態:同じ Tag() の呼び出しで 中身が派生側になる
  • Unity 橋渡しで出す Enemy とは 別名にしてあります(あとで Enemy を新しく学ぶときと混ざりにくくするため)

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

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


🔹 Day30 の振り返り(1分)

  • LINQ … Where / Count で列を短く書けました
  • 今日のポイントメソッド名は同じ Tag() のまま、インスタンスの種類で返す文字列が変わることを virtual / override で確かめます

🔹 今日のポイント

やりたいこと
基底型の変数に派生を入れるUnit u = new Slime();
多態で呼ぶConsole.WriteLine(u.Tag()); → [Slime]
配列に混ぜるUnit[] units = { new Slime(), new Boss(), new Unit() };

進め方(10分の使い方)

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

1限の過ごし方(目安)

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

提出ルール(重要)

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

■ 問題1(基礎)

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

  1. Unit 型の変数 u に new Slime() を代入する
  2. Console.WriteLine(u.Tag()); を 1回呼ぶ
  • 教材の目安の出力:[Slime]1行

■ 問題2(条件)

次の units 配列を Run() の中に用意し、foreach (Unit x in units) で Tag() を表示してください(1行に1つの文字列)。

Unit[] units =
{
    new Slime(),
    new Goblin(),
    new Boss(),
};
  • 教材の目安:[Slime] / [Goblin] / [Boss] の 3行

■ 問題3(集計)

同じ units 配列について、Tag() が返す文字列に "l"(エル小文字)を含む Unit が 何個かを数え、個数だけを1行で表示してください。

  • ヒント:Tag() は 文字列です。"l" を含むかは Contains で調べられます(Day25 付近の復習)
  • 教材のデータでは [Slime] と [Goblin] の 2個[Boss] は含みません)なので、出力は 2

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

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

Unit[] units2 =
{
    new Slime(),
    new Goblin(),
    new Boss(),
    new Slime(),
};

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

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

目安:長さ 7 以上は [Slime](7) と [Goblin](8) のみ(3体)。合計 22、平均 7、最大 8、最小 7


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

Run の外に private static bool IsBossTag(Unit u) を 1つ定義してください。

  • u.Tag() が "Boss" という部分文字列を含むとき trueContains で判定)

units2 について、IsBossTag(u) が true になる Unit の Tag() を1行ずつ表示してください。

  • 教材の目安:[Boss] の 1行
// 呼び出しのイメージ
foreach (Unit u in units2)
{
    if (IsBossTag(u))
    {
        Console.WriteLine(u.Tag());
    }
}

⚠️ つまずきやすい点

  • Unit u = new Unit(); と new Slime() … 後者は Tag() が [Slime] になります
  • Contains("l") … 大文字の L ではなく、問題文どおり 小文字の l です

🎯 今日の目的

  • 基底型の変数・配列に 派生のインスタンスを入れ、同じメソッド呼び出しで中身が変わることを体感する(Unity の 継承とオーバーライドの入口)

次へ

Day32 では interface を使い、別名のクラスを 同じインターフェース型でまとめます。講師・Slack の指示に従って進めてください。

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

広告

Unity

Posted by hidepon