# Question13 - 継承 本資料の練習問題は、複数のプログラミング言語(Java / C# / PHP / Python)で共通して利用できるよう記述されています。静的型付け・動的型付けの違いや文字列の連結ルールなど、言語固有の文法仕様に基づき、問題文の表現をご使用の言語の仕様に適宜読み替えて進めてください。 ## この問題のねらい - 継承を使って、共通の性質・振る舞いを持つ複数の種類を、重複を排除して表現できること - 継承先で、継承元の振る舞いの一部だけを独自の内容に置き換え(上書き)できること - 継承元の初期化処理や振る舞いを、継承先から適切に呼び出し・利用できること - あるクラスを継承したクラスを、さらに継承して性質を拡張できること 以下の設問はそれぞれ独立したプログラムとして実装してください。ただし、設問3・4で作成する「Hero」「Slime」は設問5で、設問6で作成する「SuperHero」は設問7で、それぞれ再利用します。 --- ## 共通の下地1:Animal(設問1・2で使用) 次の性質・振る舞いを持つ「Animal」を作成してください(この後の設問では、これを継承する形で取り組んでください)。 - 保持するデータ:名前(文字列、完全非公開) - 振る舞い - 走る:`{名前}は走りました。` と出力する - 食べる:`{名前}は食事をしました。` と出力する - 名前を設定する/取得する(アクセサ) --- ## 設問1 Animalの性質・振る舞いをすべて引き継いだ「Cat」クラスを、継承を使って定義してください。追加の振る舞いは不要です(Animalの振る舞いをそのまま使います)。 次の処理を行うプログラムを作成してください。 1. Catのインスタンスを生成する 2. 名前に `タマ` を設定する 3. 走る振る舞いを実行する(期待出力:`タマは走りました。`) 4. 食べる振る舞いを実行する(期待出力:`タマは食事をしました。`) --- ## 設問2 Animalの性質・振る舞いを引き継いだ「Dog」クラスを、継承を使って定義してください。ただし、「食べる」の振る舞いだけは独自の内容に置き換え(上書き)てください。「走る」は引き継いだままの内容を使います。 - 食べる(上書き後):`{名前}はドッグフードを食べました。` と出力する 次の処理を行うプログラムを作成してください。 1. Dogのインスタンスを生成する 2. 名前に `ポチ` を設定する 3. 走る振る舞いを実行する(期待出力:`ポチは走りました。`) 4. 食べる振る舞いを実行する(期待出力:`ポチはドッグフードを食べました。`) --- ## 共通の下地2:Character(設問3・4・6・7で使用) 次の性質・振る舞いを持つ「Character」クラスを作成してください(この後の設問では、これを継承する形で取り組んでください)。 - 保持するデータ(いずれも完全非公開) - 名前(文字列。値を設定しない間の初期値は `キャラクター`) - 体力(整数) - 力(整数) - 防御力(整数) - 生成方法:生成時に体力・力・防御力の初期値を指定できる - 振る舞い - 名前を設定する/取得する(アクセサ) - 攻撃する:自身の「力」の値をそのまま返す - ダメージを受ける(相手の攻撃値を受け取る) 1. ダメージ量 = 受け取った攻撃値 − 自身の防御力(ただし、この結果が0以下になる場合はダメージ量を1とする) 2. 自身の体力からダメージ量を引く 3. 体力が0以下になった場合は、体力を0に補正し、「戦闘不能」の状態とする 4. 次の内容をこの順番で出力する - `{名前}は{ダメージ量}のダメージを受けた。` - `{名前}の残り体力は{体力}。` - 戦闘不能になった場合のみ、さらに `{名前}はちからつきた。` - `↓` 5. 戦闘不能になったかどうかを真偽値で返す - パラメーター表示:名前・体力・力・防御力を含む、次の形式の複数行の文字列を**返す**(出力ではなく、呼び出し元に返す文字列である点に注意) ``` 名 前:{名前} 体 力:{体力}  力 :{力} 耐 久:{防御力} ``` --- ## 設問3 Characterの性質・振る舞いを引き継いだ「Hero」クラスを、継承を使って定義してください。 - Heroを生成する際は、呼び出し側が数値を指定しなくても、必ず体力25・力10・防御力7で初期化されるようにしてください。 - 追加の振る舞いは不要です。 次の処理を行うプログラムを作成してください。 1. Heroのインスタンスを生成する 2. 名前に `勇者` を設定する 3. パラメーター表示の文字列を取得し、出力する 期待出力: ``` 名 前:勇者 体 力:25  力 :10 耐 久:7 ``` --- ## 設問4 Characterの性質・振る舞いを引き継いだ「Slime」クラスを、継承を使って定義してください。 - Slimeを生成する際は、呼び出し側が数値を指定しなくても、必ず体力10・力5・防御力2で初期化されるようにしてください。 - 追加の振る舞いは不要です。 次の処理を行うプログラムを作成してください。 1. Slimeのインスタンスを生成する 2. 名前に `スライム` を設定する 3. パラメーター表示の文字列を取得し、出力する 期待出力: ``` 名 前:スライム 体 力:10  力 :5 耐 久:2 ``` --- ## 設問5 設問3・4で作成した「Hero」「Slime」を使用してください。 次の処理を行うプログラムを作成してください。 1. Heroのインスタンスを生成し、名前に `勇者` を設定する 2. Slimeのインスタンスを生成し、名前に `スライム` を設定する 3. 次の手順を、いずれかの体力が0になるまで繰り返す 1. Heroが攻撃し、その攻撃値をもとにSlimeがダメージを受ける。この結果Slimeが戦闘不能になったら、Heroの勝利として繰り返しを終了する。 2. まだ終了していなければ、Slimeが攻撃し、その攻撃値をもとにHeroがダメージを受ける。この結果Heroが戦闘不能になったら、Slimeの勝利として繰り返しを終了する。 4. 戦闘が終了したら、勝利した側の名前を「○○」、敗北した側の名前を「■■」として、`○○は■■との戦闘に勝利した` の形式で出力する 「ダメージを受ける」振る舞いを実行するたびに、その振る舞い自体が経過を表すメッセージを自動的に出力する点に注意してください(この設問側で個別に出力する必要はありません)。上記の値・アルゴリズムどおりに実装した場合、出力は次の順序・内容になります。 ``` スライムは8のダメージを受けた。 スライムの残り体力は2。 ↓ 勇者は1のダメージを受けた。 勇者の残り体力は24。 ↓ スライムは8のダメージを受けた。 スライムの残り体力は0。 スライムはちからつきた。 ↓ 勇者はスライムとの戦闘に勝利した ``` --- ## Item(設問6・7で使用) 次の性質を持つ「Item」クラスを作成してください(この後の設問で使用します)。 - 保持するデータ(いずれも完全非公開) - 装備品名(文字列) - 追加ダメージ量(整数) - 生成方法:生成時に装備品名・追加ダメージ量の初期値を指定できる - 各データについて、値を設定する/取得する(アクセサ) --- ## 設問6 設問3で作成した「Hero」の性質・振る舞いをさらに引き継いだ「SuperHero」クラスを、継承を使って定義してください。 - SuperHeroを生成する際の体力・力・防御力の初期値は、Heroと同じ(体力25・力10・防御力7)とする。 - SuperHeroは新たに、装備品(Item)を1つ保持できるようにする。装備品については、値を設定する/取得する(アクセサ)を用意する。 - 「攻撃する」振る舞いを独自の内容に置き換え(上書き)る:自身の「力」の値に、保持している装備品の「追加ダメージ量」を加算した値を返すようにする。 次の処理を行うプログラムを作成してください。 1. SuperHeroのインスタンスを生成し、名前に `勇者(装備あり)` を設定する 2. Slime(設問4)のインスタンスを生成し、名前に `スライム` を設定する 3. Itemのインスタンスを、装備品名 `こんぼう`・追加ダメージ量 `5` として生成する 4. SuperHeroの装備品として、3で生成したItemを設定する 5. SuperHeroの攻撃する振る舞いを実行し、戻り値を出力する 期待出力:`15` --- ## 設問7 設問6で作成した「SuperHero」と、設問4の「Slime」を使用してください。 次の処理を行うプログラムを作成してください。 1. SuperHeroのインスタンスを生成し、名前に `勇者(装備あり)` を設定する 2. Slimeのインスタンスを生成し、名前に `スライム` を設定する 3. Itemのインスタンスを、装備品名 `ロングソード`・追加ダメージ量 `20` として生成する 4. SuperHeroの装備品として、3で生成したItemを設定する 5. 次の手順を、いずれかの体力が0になるまで繰り返す 1. SuperHeroが攻撃し、その攻撃値をもとにSlimeがダメージを受ける。この結果Slimeが戦闘不能になったら、SuperHeroの勝利として繰り返しを終了する。 2. まだ終了していなければ、Slimeが攻撃し、その攻撃値をもとにSuperHeroがダメージを受ける。この結果SuperHeroが戦闘不能になったら、Slimeの勝利として繰り返しを終了する。 6. 戦闘が終了したら、勝利した側の名前を「○○」、敗北した側の名前を「■■」として、`○○は■■との戦闘に勝利した` の形式で出力する 上記の値・アルゴリズムどおりに実装した場合、出力は次の順序・内容になります(SuperHeroの攻撃値は 力10+追加ダメージ20=30 となり、Slimeは初回の攻撃で戦闘不能になります)。 ``` スライムは28のダメージを受けた。 スライムの残り体力は0。 スライムはちからつきた。 ↓ 勇者(装備あり)はスライムとの戦闘に勝利した ```