5-3.クラス-抽象クラス

はじめに

5-3-1、5-3-2で作成するプログラム(演習課題も含む)を保存するためのパッケージを作成する。

  • パッケージ名
    web._05._0302

5-3-3で作成するプログラム(演習課題も含む)を保存するためのパッケージを作成する。

  • パッケージ名
    web._05._0303

5-3-1

抽象クラス-1次職クラス群

1次職としてFighterクラスとMagicianクラスを作成したが、今後も様々なクラスを作成する予定である。
作成予定のクラスも考慮して改めて内容をまとめた結果、一部のメソッドは全ての1次職クラスで利用することがわかった。
今後の1次職クラス作成における親クラスとすべく、FighterクラスとMagicianクラスの共通部分をまとめ、1次職の抽象クラスを作成しよう!

【フィールド・メソッドの整理】
フィールド/クラス Fighter Magician
shield(盾) 定義済 未定義
wand(杖) 未定義 定義済
メソッド/クラス Fighter Magician
attack
(物理攻撃)
HPの0.6倍 HPの0.6倍
attackMagic
(魔法攻撃)
未定義 SPの0.4倍
useXXX
(特殊スキル)
バッシュを使う めらを使う
canUseXXX
(特殊スキル発動確認)
バッシュが使用可能か否か めらが使用可能か否か
shield(盾)の
setter・getter
定義済 未定義
wand(杖)のsetter・getter 未定義 定義済
viewInfo
(情報表示)
以下の情報を表示
親クラスの情報
盾の守備力
以下の情報を表示
親クラスの情報
杖の魔力
【共通フィールド・メソッド】
  • 共通フィールド
    なし

  • 共通メソッド(全て or 部分)
    1.attack(物理攻撃)
    2.viewInfo(情報表示) ※親クラスの情報表示は共通、+αはクラスによって異なる

【実装手順】
  1. 1次職の抽象クラスを作成し、共通フィールドとメソッドを定義する。
  2. ここでは、作成した抽象クラスを『1次職抽象クラス』と呼ぶ。
    Fighterクラス・Magicianクラスは1次職抽象クラスを継承する。
  3. 実装クラス(Fighterクラス・Magicianクラス)から、1次職抽象クラスにまとめた個所を除外する。
  4. 実装クラス(Fighterクラス・Magicianクラス)で実装が必要な抽象メソッドを作成する。
【修正したクラスファイル】
1次職抽象クラス

AbstractFirstJob.java

package web._05._0302; /** * 5-3: * AbstractFirstJobクラスは、1次職の抽象クラスです。 * MainCharacterクラスを継承します。 * AbstractFirstJobクラスは、攻撃メソッドとステータス表示メソッドを持ちます。 * また、職業特有のステータスを表示する抽象メソッドを定義します。 * * @author akira_ishii * */ abstract class AbstractFirstJob extends MainCharacter { /** * コンストラクタ * 性別コード・髪型コード・目の色コードを初期化します。 * 性別コード・髪型コード・目の色コードは引数の値を設定します。 * * @param genderCode 性別コード * @param hairStyleCode 髪型コード * @param eyeColorCode 目の色コード */ public AbstractFirstJob(String genderCode, String hairStyleCode, String eyeColorCode) { super(genderCode, hairStyleCode, eyeColorCode); } /** * モンスターに攻撃します。 * 残りヒットポイントの6割をダメージとしてモンスターに与えます。 * 与えたダメージを結果として返します。 * * @param monster モンスター * @return モンスターに与えたダメージ */ public int attack(Monster monster) { int damage = (int)(this.hp * 0.6); monster.setHp(monster.getHp() - damage); return damage; } /** * ステータスを表示します。 * キャラクターの情報に加えて、各職業独自のフィールドを表示します。 * */ @Override public void viewInfo() { super.viewInfo(); addInfo(); } /** * ステータス表示時、各職業独自のフィールドも表示します。 * */ abstract void addInfo(); }
Fighterクラス(抽象クラスを継承)

Fighter.java

package web._05._0302; /** * 5-1: * Fighterクラスは、1次職「Fighter」を表します。 * AbstractFirstJobクラスを継承し、フィールドとして盾の守備力を持ちます。 * Fighterクラスは、フィールドのsetter・getterや特殊スキル「バッシュ」関連などのメソッドを持ちます。 * また、ステータスの追加表示を行う抽象メソッドを実装します。 * * @author akira_ishii * */ public class Fighter extends AbstractFirstJob { /** 盾の守備力 */ protected int shield; /** * コンストラクタ * 性別コード・髪型コード・目の色コード・ヒットポイント・スキルポイント・盾を初期化します。 * 性別コード・髪型コード・目の色コードは引数の値を設定し、 * ヒットポイントの初期値は100、スキルポイントの初期値は30、盾の初期値は5とします。 * * @param genderCode 性別コード * @param hairStyleCode 髪型コード * @param eyeColorCode 目の色コード */ public Fighter(String genderCode, String hairStyleCode, String eyeColorCode) { super(genderCode, hairStyleCode, eyeColorCode); this.hp = 100; this.sp = 30; this.shield = 5; } /** * 特殊スキル「バッシュ」を使います。 * 残りヒットポイントの17割をダメージとしてモンスターに与えます。 * 与えたダメージを結果として返します。 * また、スキルポイントを10消費します。 * * @param monster モンスター * @return モンスターに与えたダメージ */ public int useBash(Monster monster) { int damage = (int)(this.hp * 1.7); monster.setHp(monster.getHp() - damage); this.sp = this.sp - 10; return damage; } /** * 特殊スキル「バッシュ」を使えるか判断します。 * スキルポイントが10以上で使用可能、それより小さい場合は使用不可となります。 * * @return true:使用可 false:使用不可 */ public boolean canUseBash() { return 10 <= this.sp; } /** * 盾の守備力を返します。 * * @return 盾の守備力 */ public int getShield() { return this.shield; } /** * 盾の守備力を設定します。 * * @param shield 盾の守備力 */ public void setShield(int shield) { this.shield = shield; } /** * Fighter独自のステータスを表示します。 * 盾の守備力を表示します。 * */ @Override void addInfo() { System.out.println("盾の守備力:" + this.shield); } }
Magicianクラス(抽象クラスを継承)

※自分で作成したMagicianクラスで試してみてください。
必須ではありません。

【テストパターン】
考え方
・5-1で動作確認したテストクラスを使用し、1次職抽象クラスを継承したFighterクラス・Magicianクラスが
 継承前と同様に正しく動作することを確認する。

5-3-2

抽象クラス-2次職クラス群

1次職と同様に現在作成中のFighterの2次職クラスも抽象クラス(ここで作成する抽象クラスを2次職抽象クラスと呼称する)を使って整理することになった。
現在作成が完了しているのは、AxMaster・LanceMaster・SwordMaster の3種である。
現在のクラス構成(継承や実装)を図にすると以下のようになる。

今回、AxMaster・LanceMaster・SwordMaster の共通(部分・全体)フィールド・メソッドをまとめた2次職抽象クラスを作成し、全体を再実装(2次職抽象クラスを継承した形)すること。
最終的にクラスの構成(継承や実装)を下図のようにする。

作成するクラス

AxMaster・LanceMaster・SwordMaster の共通(部分・全体)フィールド・メソッドをまとめた2次職抽象クラス

2次職抽象クラス作成に伴う変更内容
  1. AxMaster・LanceMaster・SwordMasterは、2次職抽象クラスを extends し、IFighterSecondJob を implements しない。
  2. AxMaster・LanceMaster・SwordMasterは、2次職抽象クラスの extends に伴い、ソースコードを整理する。
  3. 2次職抽象クラスがIFighterSecondJobの実装(implements)およびFighterクラスの継承(extends)をする。
補足

AxMaster・LanceMaster・SwordMasterは2次職抽象クラスを継承するのみとなるが、2次職抽象クラスがFighterクラスの継承およびIFighterSecondJobの実装しているため影響はでない。

提出時の注意点

以下3ファイルも同じパッケージに含めること。

  • AbstractFirstJob.java
  • Fighter.java
  • IFighterSecondJob
【既存ソースコード】
以下AxMaster~IFighterSecondJob+5-3-1の3クラスまとめて一式

必要なソースコード一式(右クリック⇒名前を付けてリンク先を保存)

AxMaster

AxMaster.java

package web._05._0302; import java.util.Random; /** * 5-3-2: * AxMasterクラスは、2次職「AxMaster」を表します。 * Fighterクラスを継承し、IFighterSecondJobを実装します。 * マジックポイントをフィールドとして持ちます。 * AxMasterクラスは、フィールドのgetter・setterや自動回復メソッドを持ちます。 * また、攻撃メソッドとステータス表示メソッドをオーバーライドします。 * * @author akira_ishii * */ public class AxMaster extends Fighter implements IFighterSecondJob { /** マジックポイント */ protected int mp; /** * コンストラクタ * 性別コード・髪型コード・目の色コード・ヒットポイント・スキルポイント・マジックポイントを初期化します。 * 性別コード・髪型コード・目の色コードは引数の値を設定し、 * ヒットポイントの初期値は160、スキルポイントの初期値は40、マジックポイントの初期値は5とします。 * * @param genderCode 性別コード * @param hairStyleCode 髪型コード * @param eyeColorCode 目の色コード */ public AxMaster(String genderCode, String hairStyleCode, String eyeColorCode) { super(genderCode, hairStyleCode, eyeColorCode); this.hp = 160; this.sp = 40; this.mp = 5; } /** * モンスターに攻撃します。 * 通常、残りヒットポイントの8割をダメージとしてモンスターに与えます。 * 特殊攻撃が発生する確率は10%で、発生した場合は残りヒットポイントの8割を追加ダメージとして加えます。 * 合計ダメージを結果として返します。 * * @param Monster モンスター * @return モンスターに与えたダメージ */ @Override public int attack(Monster monster) { int damage = (int)(this.hp * 0.8); Random rnd = new Random(); int num = rnd.nextInt(10); //発生確率約10% if(num == 9) { damage = damage + (int)(this.hp * 0.8); } return damage; } /** * ヒットポイントを自動回復します。 * 自身のヒットポイントをマジックポイントの半分回復させます。 * 回復後ヒットッポイントが160を超える場合は160に更新します。 * */ @Override public void healAuto() { this.hp = this.hp + this.mp / 2; if(160 < this.hp) { this.hp = 160; } } /** * マジックポイントを設定します。 * * @param mp マジックポイント */ public void setMp(int mp) { this.mp = mp; } /** * マジックポイントを返します。 * * @return MP マジックポイント */ public int getMp() { return this.mp; } /** * ステータスを表示します。 * ファイターの情報に加えて、マジックポイントを表示します。 * */ @Override public void viewInfo() { super.viewInfo(); System.out.println("MP:" + this.mp); } }
LanceMaster

LanceMaster.java

package web._05._0302; import java.util.Random; /** * 5-3-2: * LanceMasterクラスは、2次職「LanceMaster」を表します。 * Fighterクラスを継承し、IFighterSecondJobを実装します。 * マジックポイントをフィールドとして持ちます。 * LanceMasterクラスは、フィールドのgetter・setterや自動回復メソッドを持ちます。 * また、攻撃メソッドとステータス表示メソッドをオーバーライドします。 * * @author akira_ishii * */ public class LanceMaster extends Fighter implements IFighterSecondJob { /** マジックポイント */ protected int mp; /** * コンストラクタ * 性別コード・髪型コード・目の色コード・ヒットポイント・スキルポイント・マジックポイントを初期化します。 * 性別コード・髪型コード・目の色コードは引数の値を設定し、 * ヒットポイントの初期値は120、スキルポイントの初期値は50、マジックポイントの初期値は15とします。 * * @param genderCode 性別コード * @param hairStyleCode 髪型コード * @param eyeColorCode 目の色コード */ public LanceMaster(String genderCode, String hairStyleCode, String eyeColorCode) { super(genderCode, hairStyleCode, eyeColorCode); this.hp = 120; this.sp = 50; this.mp = 15; } /** * モンスターに攻撃します。 * 通常、残りヒットポイントの8割をダメージとしてモンスターに与えます。 * 特殊攻撃が発生する確率は33%で、発生した場合は固定ダメージ30を追加ダメージとして加えます。 * 与えたダメージを結果として返します。 * * @param Monster モンスター * @return モンスターに与えたダメージ */ @Override public int attack(Monster monster) { int damage = (int)(this.hp * 0.8); Random rnd = new Random(); int num = rnd.nextInt(3); //発生確率約33% if(num == 2) { damage = damage + 30; } return damage; } /** * ヒットポイントを自動回復します。 * 自身のヒットポイントをマジックポイントの半分回復させます。 * 回復後ヒットッポイントが120を超える場合は120に更新します。 * */ @Override public void healAuto() { this.hp = this.hp + this.mp / 2; //回復した結果、最大値を超えた場合は if(120 < this.hp) { this.hp = 120; } } /** * マジックポイントを設定します。 * * @param mp マジックポイント */ public void setMp(int mp) { this.mp = mp; } /** * マジックポイントを返します。 * * @return MP マジックポイント */ public int getMp() { return this.mp; } /** * ステータスを表示します。 * ファイターの情報に加えて、マジックポイントを表示します。 * */ @Override public void viewInfo() { super.viewInfo(); System.out.println("MP:" + this.mp); } }
SwordMaster

SwordMaster.java

package web._05._0302; import java.util.Random; /** * 5-3-2: * SwordMasterクラスは、2次職「SwordMaster」を表します。 * Fighterクラスを継承し、IFighterSecondJobを実装します。 * マジックポイントをフィールドとして持ちます。 * SwordMasterクラスは、フィールドのgetter・setterや自動回復メソッドを持ちます。 * また、攻撃メソッドとステータス表示メソッドをオーバーライドします。 * * @author akira_ishii * */ public class SwordMaster extends Fighter implements IFighterSecondJob { /** マジックポイント */ protected int mp; /** * コンストラクタ * 性別コード・髪型コード・目の色コード・ヒットポイント・スキルポイント・マジックポイントを初期化します。 * 性別コード・髪型コード・目の色コードは引数の値を設定し、 * ヒットポイントの初期値は130、スキルポイントの初期値は45、マジックポイントの初期値は20とします。 * * @param genderCode 性別コード * @param hairStyleCode 髪型コード * @param eyeColorCode 目の色コード */ public SwordMaster(String genderCode, String hairStyleCode, String eyeColorCode) { super(genderCode, hairStyleCode, eyeColorCode); this.hp = 130; this.sp = 45; this.mp = 20; } /** * モンスターに攻撃します。 * 通常、残りヒットポイントの8割をダメージとしてモンスターに与えます。 * 特殊攻撃が発生する確率は25%で、発生した場合は残りスキルポイントの8割を追加ダメージとして加えます。 * 与えたダメージを結果として返します。 * * @param Monster モンスター * @return モンスターに与えたダメージ */ @Override public int attack(Monster monster) { int damage = (int)(this.hp * 0.8); Random rnd = new Random(); int num = rnd.nextInt(4); //発生確率約25% if(num == 3) { damage = damage + (int)(this.sp * 0.8); } return damage; } /** * ヒットポイントを自動回復します。 * 自身のヒットポイントをマジックポイントの半分回復させます。 * 回復後ヒットッポイントが130を超える場合は130に更新します。 * */ @Override public void healAuto() { this.hp = this.hp + this.mp / 2; if(130 < this.hp) { this.hp = 130; } } /** * マジックポイントを設定します。 * * @param mp マジックポイント */ public void setMp(int mp) { this.mp = mp; } /** * マジックポイントを返します。 * * @return MP マジックポイント */ public int getMp() { return this.mp; } /** * ステータスを表示します。 * ファイターの情報に加えて、マジックポイントを表示します。 * */ @Override public void viewInfo() { super.viewInfo(); System.out.println("MP:" + this.mp); } }
IFighterSecondJob

IFighterSecondJob.java

package web._05._0302; /** * 5-3-2: * IFighterSecondJobは、2次職のインターフェースです。 * 実装クラスが持つべき自動回復メソッドを定義します。 * * @author akira_ishii * */ public interface IFighterSecondJob { /** * ヒットポイントを自動回復します。 * */ void healAuto(); }
【テストパターン】
考え方
・動作確認用のテストクラスを実行し、抽象クラス使用前・使用後で結果が変わらないことを確認する。
【テストクラス】
以下AxMaster:テストクラス~SwordMaster:テストクラスまとめて一式

テストクラス一式:右クリック⇒名前を付けてリンク先を保存

AxMaster:テストクラス

TestAxMaster.java

package web._05._0302; /** * 5-3-2: * TestAxMasterクラスは、AxMasterクラスの動作確認をします。 * * @author akira_ishii * */ public class TestAxMaster { /** * AxMasterクラスの各機能の動作確認を行います。 * * @param args コマンドライン引数 */ public static void main(String[] args) { AxMaster axMaster = new AxMaster("1", "1", "1"); //初期ステータスの確認 //結果、trueなら正 System.out.println("性別コードの期待値:1"); System.out.println("性別コードの結果:" + axMaster.getGenderCode()); System.out.println("期待値=結果:" + axMaster.getGenderCode().equals("1")); System.out.println("髪型コードの期待値:1"); System.out.println("髪型コードの結果:" + axMaster.getHairStyleCode()); System.out.println("期待値=結果:" + axMaster.getHairStyleCode().equals("1")); System.out.println("目の色コードの期待値:1"); System.out.println("目の色コードの結果:" + axMaster.getEyeColorCode()); System.out.println("期待値=結果:" + axMaster.getEyeColorCode().equals("1")); System.out.println("HPの期待値:160"); System.out.println("HPの結果:" + axMaster.getHp()); System.out.println("期待値=結果:" + (axMaster.getHp() == 160)); System.out.println("SPの期待値:40"); System.out.println("SPの結果:" + axMaster.getSp()); System.out.println("期待値=結果:" + (axMaster.getSp() == 40)); System.out.println("MPの期待値:5"); System.out.println("MPの結果:" + axMaster.getMp()); System.out.println("期待値=結果:" + (axMaster.getMp() == 5)); //ステータス表示メソッドの動作確認 //正しく表示されることを確認する System.out.println("ステータス表示メソッドが正しく動作していることを目視確認する"); axMaster.viewInfo(); /* * 攻撃メソッドは確率で結果が変わるため、 * 現在の形では動作確認が難しい */ //自動回復動作確認 //次の3ケースで動作を確認します。回復量は2。 //①回復して160より小さい→2回復される //②回復して160ちょうど→2回復される //③回復して160を超える→160に調整される //① System.out.println("ケース①:回復して160より小さい→2回復される"); System.out.println("150をHPにセット"); axMaster.setHp(150); System.out.println("healAutoメソッドを実行"); axMaster.healAuto(); //結果、trueなら正 System.out.println("HPの期待値:152"); System.out.println("HPの結果:" + axMaster.getHp()); System.out.println("期待値=結果:" + (axMaster.getHp() == 152)); //② System.out.println("ケース②:回復して160ちょうど→2回復される"); System.out.println("158をHPにセット"); axMaster.setHp(158); System.out.println("healAutoメソッドを実行"); axMaster.healAuto(); //結果、trueなら正 System.out.println("HPの期待値:160"); System.out.println("HPの結果:" + axMaster.getHp()); System.out.println("期待値=結果:" + (axMaster.getHp() == 160)); //③ System.out.println("ケース③:回復して160を超える→160に調整される"); System.out.println("159をHPにセット"); axMaster.setHp(159); System.out.println("healAutoメソッドを実行"); axMaster.healAuto(); //結果、trueなら正 System.out.println("HPの期待値:160"); System.out.println("HPの結果:" + axMaster.getHp()); System.out.println("期待値=結果:" + (axMaster.getHp() == 160)); } }
LanceMaster:テストクラス

TestLanceMaster.java

package web._05._0302; /** * 5-3-2: * TestLanceMasterクラスは、LanceMasterクラスの動作確認をします。 * * @author akira_ishii * */ public class TestLanceMaster { /** * LanceMasterクラスの各機能の動作確認を行います。 * * @param args コマンドライン引数 */ public static void main(String[] args) { LanceMaster lanceMaster = new LanceMaster("1", "1", "1"); //初期ステータスの確認 //結果、trueなら正 System.out.println("性別コードの期待値:1"); System.out.println("性別コードの結果:" + lanceMaster.getGenderCode()); System.out.println("期待値=結果:" + lanceMaster.getGenderCode().equals("1")); System.out.println("髪型コードの期待値:1"); System.out.println("髪型コードの結果:" + lanceMaster.getHairStyleCode()); System.out.println("期待値=結果:" + lanceMaster.getHairStyleCode().equals("1")); System.out.println("目の色コードの期待値:1"); System.out.println("目の色コードの結果:" + lanceMaster.getEyeColorCode()); System.out.println("期待値=結果:" + lanceMaster.getEyeColorCode().equals("1")); System.out.println("HPの期待値:120"); System.out.println("HPの結果:" + lanceMaster.getHp()); System.out.println("期待値=結果:" + (lanceMaster.getHp() == 120)); System.out.println("SPの期待値:50"); System.out.println("SPの結果:" + lanceMaster.getSp()); System.out.println("期待値=結果:" + (lanceMaster.getSp() == 50)); System.out.println("MPの期待値:15"); System.out.println("MPの結果:" + lanceMaster.getMp()); System.out.println("期待値=結果:" + (lanceMaster.getMp() == 15)); //ステータス表示メソッドの動作確認 //正しく表示されることを確認する System.out.println("ステータス表示メソッドが正しく動作していることを目視確認する"); lanceMaster.viewInfo(); /* * 攻撃メソッドは確率で結果が変わるため、 * 現在の形では動作確認が難しい */ //自動回復動作確認 //次の3ケースで動作を確認します。回復量は7。 //①回復して120より小さい→7回復される //②回復して120ちょうど→7回復される //③回復して120を超える→120に調整される //① System.out.println("ケース①:回復して120より小さい→7回復される"); System.out.println("110をHPにセット"); lanceMaster.setHp(110); System.out.println("healAutoメソッドを実行"); lanceMaster.healAuto(); //結果、trueなら正 System.out.println(lanceMaster.getHp() == 117); System.out.println("HPの期待値:117"); System.out.println("HPの結果:" + lanceMaster.getHp()); System.out.println("期待値=結果:" + (lanceMaster.getHp() == 117)); //② System.out.println("ケース②:回復して120ちょうど→7回復される"); System.out.println("113をHPにセット"); lanceMaster.setHp(113); System.out.println("healAutoメソッドを実行"); lanceMaster.healAuto(); //結果、trueなら正 System.out.println("HPの期待値:120"); System.out.println("HPの結果:" + lanceMaster.getHp()); System.out.println("期待値=結果:" + (lanceMaster.getHp() == 120)); //③ System.out.println("ケース③:回復して120を超える→120に調整される"); System.out.println("115をHPにセット"); lanceMaster.setHp(115); System.out.println("healAutoメソッドを実行"); lanceMaster.healAuto(); //結果、trueなら正 System.out.println(lanceMaster.getHp() == 120); System.out.println("HPの期待値:120"); System.out.println("HPの結果:" + lanceMaster.getHp()); System.out.println("期待値=結果:" + (lanceMaster.getHp() == 120)); } }
SwordMaster:テストクラス

TestSwordMaster.java

package web._05._0302; /** * 5-3-2: * TestSwordMasterクラスは、SwordMasterクラスの動作確認をします。 * * @author akira_ishii * */ public class TestSwordMaster { /** * SwordMasterクラスの各機能の動作確認を行います。 * * @param args コマンドライン引数 */ public static void main(String[] args) { SwordMaster swordMaster = new SwordMaster("1", "1", "1"); //初期ステータスの確認 //結果、trueなら正 System.out.println("性別コードの期待値:1"); System.out.println("性別コードの結果:" + swordMaster.getGenderCode()); System.out.println("期待値=結果:" + swordMaster.getGenderCode().equals("1")); System.out.println("髪型コードの期待値:1"); System.out.println("髪型コードの結果:" + swordMaster.getHairStyleCode()); System.out.println("期待値=結果:" + swordMaster.getHairStyleCode().equals("1")); System.out.println("目の色コードの期待値:1"); System.out.println("目の色コードの結果:" + swordMaster.getEyeColorCode()); System.out.println("期待値=結果:" + swordMaster.getEyeColorCode().equals("1")); System.out.println("HPの期待値:130"); System.out.println("HPの結果:" + swordMaster.getHp()); System.out.println("期待値=結果:" + (swordMaster.getHp() == 130)); System.out.println("SPの期待値:45"); System.out.println("SPの結果:" + swordMaster.getSp()); System.out.println("期待値=結果:" + (swordMaster.getSp() == 45)); System.out.println("MPの期待値:20"); System.out.println("MPの結果:" + swordMaster.getMp()); System.out.println("期待値=結果:" + (swordMaster.getMp() == 20)); //ステータス表示メソッドの動作確認 //正しく表示されることを確認する System.out.println("ステータス表示メソッドが正しく動作していることを目視確認する"); swordMaster.viewInfo(); /* * 攻撃メソッドは確率で結果が変わるため、 * 現在の形では動作確認が難しい */ //自動回復動作確認 //次の3ケースで動作を確認します。回復量は10。 //①回復して130より小さい→10回復される //②回復して130ちょうど→10回復される //③回復して130を超える→130に調整される //① System.out.println("ケース①:回復して130より小さい→10回復される"); System.out.println("115をHPにセット"); swordMaster.setHp(115); System.out.println("healAutoメソッドを実行"); swordMaster.healAuto(); //結果、trueなら正 System.out.println("HPの期待値:125"); System.out.println("HPの結果:" + swordMaster.getHp()); System.out.println("期待値=結果:" + (swordMaster.getHp() == 125)); //② System.out.println("ケース②:回復して130ちょうど→10回復される"); System.out.println("120をHPにセット"); swordMaster.setHp(120); System.out.println("healAutoメソッドを実行"); swordMaster.healAuto(); //結果、trueなら正 System.out.println("HPの期待値:130"); System.out.println("HPの結果:" + swordMaster.getHp()); System.out.println("期待値=結果:" + (swordMaster.getHp() == 130)); //③ System.out.println("ケース③:回復して130を超える→130に調整される"); System.out.println("125をHPにセット"); swordMaster.setHp(125); System.out.println("healAutoメソッドを実行"); swordMaster.healAuto(); //結果、trueなら正 System.out.println("HPの期待値:130"); System.out.println("HPの結果:" + swordMaster.getHp()); System.out.println("期待値=結果:" + (swordMaster.getHp() == 130)); } }

5-3-3

抽象クラス-顧客行動管理システム

来店する顧客(主婦、社会人、学生)の行動をプログラム化した主婦クラス・社会人クラス・学生クラスが現在あるため、それらの共通部分をまとめた抽象クラスを作成し再実装すること。
主婦クラス・社会人クラス・学生クラスの仕様は以下の通りである。
※実装済ソース(抽象クラス未使用)も用意してあるので、それを利用して構わない※

※結合テスト仕様書・報告書※
抽象クラスを利用した既存システムの改修が主なので、
テスト仕様書はこちらで用意したものにそって動作確認をする。
5−3−3.顧客行動管理システムテスト仕様書:右クリック⇒名前を付けてリンク先を保存

【クラス化した顧客】
  • 主婦
  • 社会人
  • 学生
【各クラスの説明】

<主婦クラス>

◇購入する商品の総額、ポイント数を算出し、表示するメソッド
 ≪商品の総額≫
  金額の合計を算出する
 ≪ポイント数≫
  総額の5%をポイントとして算出する。
 ≪購入する商品≫
  ・野菜
   レタス:800円
   トマト:700円
   インゲン:500円
  ・肉
   比内鶏:1200円
   薩摩シャモ:1200円
   名古屋コーチン:1200円
  ・魚
   まぐろ刺身:650円
   ブリ:400円
   メカジキ(照り焼き用):500円
  ・飲み物
   牛乳:198円
   玄米茶:147円
   野菜ジュース:230円
◇主婦仲間と談笑するメソッド
 ※空メソッドでよい。

<社会人クラス>

◇購入する商品の総額、ポイント数を算出し、表示するメソッド
 ≪商品の総額≫
  金額の合計を算出する
 ≪ポイント数≫
  総額の5%をポイントとして算出する。
 ≪購入する商品≫
  ・野菜
   レタス:800円
   トマト:700円
   インゲン:500円
  ・肉
   松坂牛:1500円
   神戸牛:1500円
   近江牛:1500円
  ・魚
   まぐろ刺身:650円
   ブリ:400円
   メカジキ(照り焼き用):500円
  ・飲み物
   黒ウーロン茶:211円
   ビタミンガード:168円
   ヘルシア緑茶:120円
◇帰宅するメソッド
 ※空メソッドでよい。

<学生クラス>

◇購入する商品の総額、ポイント数を算出し、表示するメソッド
 ≪商品の総額≫
  金額の合計を算出する
 ≪ポイント数≫
  総額の5%をポイントとして算出する。
 ≪購入する商品≫
  ・野菜
   レタス:800円
   トマト:700円
   インゲン:500円
  ・肉
   黒豚:1800円
   まるみ豚:1800円
   白金豚:1800円
  ・魚
   まぐろ刺身:650円
   ブリ:400円
   メカジキ(照り焼き用):500円
  ・飲み物
   緑茶:100円
   コーラ:80円
   ファンタ:50円
◇立ち読みするメソッド
 ※空メソッドでよい。
【クラス説明】
<起動クラス(Mainクラス)>

mainメソッド
以下を表示し、入力された番号に従って処理を進める。

画面レイアウト

顧客を選択してください。
※先頭の数字を入力してください。

1.主婦
2.社会人
3.学生

番号に該当するクラスのオブジェクトを作成し、機能の表示・選択メソッドを実行する。

<主婦クラス>

機能の表示・選択メソッド
使用できる機能を以下のように一覧表示し、入力された番号を読み取る。

画面レイアウト

使用する機能を選択してください。
※先頭の数字を入力してください。

1.購入商品の金額計算
2.談笑

読み取った番号に従って、該当する機能(メソッド)を実行する。

購入商品の金額計算メソッド

  1. 購入する商品を選択する(商品の金額を格納する)。
    1. 野菜選択メソッドを実行する。
    2. 肉選択メソッドを実行する。
    3. 魚選択メソッドを実行する。
    4. 飲み物選択メソッドを実行する。
  2. 商品の合計金額を算出する。
  3. ポイント数を算出する。
  4. 合計金額および、ポイント数を表示する。

談笑メソッド
空でよい。

<社会人クラス>

機能の表示・選択メソッド
使用できる機能を以下のように一覧表示し、入力された番号を読み取る。

画面レイアウト

使用する機能を選択してください。
※先頭の数字を入力してください。

1.購入商品の金額計算
2.帰宅

購入商品の金額計算メソッド

  1. 購入する商品を選択する(商品の金額を格納する)。
    1. 野菜選択メソッドを実行する。
    2. 肉選択メソッドを実行する。
    3. 魚選択メソッドを実行する。
    4. 飲み物選択メソッドを実行する。
  2. 商品の合計金額を算出する。
  3. ポイント数を算出する。
  4. 合計金額および、ポイント数を表示する。

帰宅メソッド
空でよい。

<学生クラス>

機能の表示・選択メソッド
使用できる機能を以下のように一覧表示し、入力された番号を読み取る。

画面レイアウト

使用する機能を選択してください。
※先頭の数字を入力してください。

1.購入商品の金額計算
2.立ち読み

購入商品の金額計算メソッド

  1. 購入する商品を選択する(商品の金額を格納する)。
    1. 野菜選択メソッドを実行する。
    2. 肉選択メソッドを実行する。
    3. 魚選択メソッドを実行する。
    4. 飲み物選択メソッドを実行する。
  2. 商品の合計金額を算出する。
  3. ポイント数を算出する。
  4. 合計金額および、ポイント数を表示する。

立ち読みメソッド
空でよい。

【テストパターン】
考え方
・仕様通りに動作する。
・表示された番号以外を入力する。
 未入力、数値でないもの(文字や記号)、表示された番号以外の数字
【既存ソースファイル】
以下実行クラス~学生クラス一式

必要なソースコード一式:右クリック⇒名前を付けてリンク先を保存

【実行クラス】

S533CustomerBehaviorManagement.java

package web._05._0303; /** * 5-3-3: * S533CustomerBehaviorManagementクラスは、顧客行動管理システムを起動します。 * * @author akira_ishii * */ public class S533CustomerBehaviorManagement { /** * メニューを表示し、コンソールで入力された顧客のメニューを表示します。 * * @param args コマンドライン引数 */ public static void main(String[] args) { System.out.println("顧客を選択してください。"); System.out.println("※先頭の数字を入力してください。"); System.out.println("1.主婦"); System.out.println("2.社会人"); System.out.println("3.学生"); String customer = new java.util.Scanner(System.in).nextLine(); if (customer.equals("1")) { S533Housewife housewife = new S533Housewife(); housewife.showMenu(); } else if (customer.equals("2")) { S533Employee adult = new S533Employee(); adult.showMenu(); } else if (customer.equals("3")) { S533Student student = new S533Student(); student.showMenu(); } else { System.out.println("1-3のどれかをお選びください。"); } } }
【主婦クラス】

S533Housewife.java

package web._05._0303; import java.util.ArrayList; import java.util.List; /** * 5-3-3: * S533Housewifeクラスは、主婦を表します。 * S533Housewifeクラスは、購入する商品を選択するメソッドや、 * 購入する商品の金額計算、談笑するメソッドなどがあります。 * * @author akira_ishii * */ public class S533Housewife { /** * メニューを表示します。 * メニューでは、「購入商品の金額計算」と「談笑」を選ぶことができます。 * */ public void showMenu() { System.out.println("使用する機能を選択してください。"); System.out.println("※先頭の数字を入力してください。"); System.out.println("1.購入商品の金額計算"); System.out.println("2.談笑"); String choice = new java.util.Scanner(System.in).nextLine(); if (choice.equals("1")) { calculationGoods(selectGoods()); } else if (choice.equals("2")) { speak(); } else { System.out.println("1-2のどれかをお選びください。"); } } /** * カゴの中の商品の総額とポイント数を計算し、表示します。 * ポイント数は総額の5%で計算します。 * カゴの中が空の場合は計算しません。 * * @param priceList 購入する商品の金額を格納したリスト */ public void calculationGoods(List<Integer> goodsList) { if (goodsList.isEmpty()) { System.out.println("カゴが空です。"); } else { int total = 0; for (Integer price : goodsList) { total = total + price.intValue(); } // Java8 int total=0 - for文を以下で表現できる // total = goodsList.stream().reduce(0, (t, v) -> t + v); System.out.println("購入した商品の総額は、" + total + "円です。"); System.out.println("ポイントは、" + (int) (total * 0.05) + "ポイントです。"); } } /** * 購入する商品を選択します。 * 商品は、野菜・肉・魚・飲み物からそれぞれ選択します。 * * @return priceList 購入する商品の金額を格納したリスト */ public List<Integer> selectGoods() { List<Integer> priceList = new ArrayList<>(); selectVegetables(priceList); selectMeat(priceList); selectFish(priceList); selectDrink(priceList); return priceList; } /** * 購入する野菜を選択し、金額を追加します。 * 800円・700円・500円の野菜を追加します。 * * @param priceList 購入する商品の金額を格納するリスト */ public void selectVegetables(List<Integer> priceList) { priceList.add(800); priceList.add(700); priceList.add(500); } /** * 購入するお肉を選択し、金額を追加します。 * 1200円の肉を3種類追加します。 * * @param priceList 購入する商品の金額を格納するリスト */ public void selectMeat(List<Integer> priceList) { priceList.add(1200); priceList.add(1200); priceList.add(1200); } /** * 購入する魚を選択し、金額を追加します。 * 650円・400円・500円の魚を追加します。 * * @param priceList 購入する商品の金額を格納するリスト */ public void selectFish(List<Integer> priceList) { priceList.add(650); priceList.add(400); priceList.add(500); } /** * 購入する飲み物を選択し、金額を追加します。 * 198円・147円・230円の飲み物を追加します。 * * @param priceList 購入する商品の金額を格納するリスト */ public void selectDrink(List<Integer> goodsList) { goodsList.add(198); goodsList.add(147); goodsList.add(230); } /** * 主婦仲間と談笑します。 * */ public void speak() { } }
【社会人クラス】

S533Employee.java

package web._05._0303; import java.util.ArrayList; import java.util.List; /** * 5-3-3: * S533Employeeクラスは、社会人を表します。 * S533Employeeクラスは、購入する商品を選択するメソッドや、 * 購入する商品の金額計算、帰宅するメソッドなどがあります。 * * @author akira_ishii * */ public class S533Employee { /** * メニューを表示します。 * メニューでは、「購入商品の金額計算」と「帰宅」を選ぶことができます。 * */ public void showMenu() { System.out.println("使用する機能を選択してください。"); System.out.println("※先頭の数字を入力してください。"); System.out.println("1.購入商品の金額計算"); System.out.println("2.帰宅"); String choice = new java.util.Scanner(System.in).nextLine(); if (choice.equals("1")) { calculationGoods(selectGoods()); } else if (choice.equals("2")) { goHome(); } else { System.out.println("1-2のどれかをお選びください。"); } } /** * カゴの中の商品の総額とポイント数を計算し、表示します。 * ポイント数は総額の5%で計算します。 * カゴの中が空の場合は計算しません。 * * @param priceList 購入する商品の金額を格納したリスト */ public void calculationGoods(List<Integer> priceList) { if (priceList.isEmpty()) { System.out.println("カゴが空です。"); } else { int total = 0; for (Integer price : priceList) { total = total + price.intValue(); } // Java8↑ int total=0 - for文を以下で表現できる // total = goodsList.stream().reduce(0, (t, v) -> t + v); System.out.println("購入する商品の総額は、" + total + "円です。"); System.out.println("ポイントは、" + (int) (total * 0.05) + "ポイントです。"); } } /** * 購入する商品を選択します。 * 商品は、野菜・肉・魚・飲み物からそれぞれ選択します。 * * @return priceList 購入する商品の金額を格納したリスト */ public List<Integer> selectGoods() { List<Integer> priceList = new ArrayList<>(); selectVegetables(priceList); selectMeat(priceList); selectFish(priceList); selectDrink(priceList); return priceList; } /** * 購入する野菜を選択し、金額を追加します。 * 800円・700円・500円の野菜を追加します。 * * @param priceList 購入する商品の金額を格納するリスト */ public void selectVegetables(List<Integer> priceList) { priceList.add(800); priceList.add(700); priceList.add(500); } /** * 購入するお肉を選択し、金額を追加します。 * 1500円の肉を3種類追加します。 * * @param priceList 購入する商品の金額を格納するリスト */ public void selectMeat(List<Integer> priceList) { priceList.add(1500); priceList.add(1500); priceList.add(1500); } /** * 購入する魚を選択し、金額を追加します。 * 650円・400円・500円の魚を追加します。 * * @param priceList 購入する商品の金額を格納するリスト */ public void selectFish(List<Integer> priceList) { priceList.add(650); priceList.add(400); priceList.add(500); } /** * 購入する飲み物を選択し、金額を追加します。 * 211円・168円・120円の飲み物を追加します。 * * @param priceList 購入する商品の金額を格納するリスト */ public void selectDrink(List<Integer> priceList) { priceList.add(211); priceList.add(168); priceList.add(120); } /** * 帰宅します。 * */ public void goHome() { } }
【学生クラス】

S533Student.java

package web._05._0303; import java.util.ArrayList; import java.util.List; /** * 5-3-3: * S533Studentクラスは、学生を表します。 * S533Studentクラスは、購入する商品を選択するメソッドや、 * 購入する商品の金額計算、立ち読みするメソッドなどがあります。 * * @author akira_ishii * */ public class S533Student { /** * メニューを表示します。 * メニューでは、「購入商品の金額計算」と「立ち読み」を選ぶことができます。 * */ public void showMenu() { System.out.println("使用する機能を選択してください。"); System.out.println("※先頭の数字を入力してください。"); System.out.println("1.購入商品の金額計算"); System.out.println("2.立ち読み"); String choice = new java.util.Scanner(System.in).nextLine(); if (choice.equals("1")) { calculationGoods(selectGoods()); } else if (choice.equals("2")) { read(); } else { System.out.println("1-2のどれかをお選びください。"); } } /** * カゴの中の商品の総額とポイント数を計算し、表示します。 * ポイント数は総額の5%で計算します。 * カゴの中が空の場合は計算しません。 * * @param priceList 購入する商品の金額を格納したリスト */ public void calculationGoods(List<Integer> priceList) { if (priceList.isEmpty()) { System.out.println("カゴが空です。"); } else { int total = 0; for (Integer price : priceList) { total = total + price.intValue(); } // Java8 int total=0 - for文を以下で表現できる // total = goodsList.stream().reduce(0, (t, v) -> t + v); System.out.println("購入した商品の総額は、" + total + "円です。"); System.out.println("ポイントは、" + (int) (total * 0.05) + "ポイントです。"); } } /** * 購入する商品を選択します。 * 商品は、野菜・肉・魚・飲み物からそれぞれ選択します。 * * @return priceList 購入する商品の金額を格納したリスト */ public List<Integer> selectGoods() { List<Integer> priceList = new ArrayList<>(); selectVegetables(priceList); selectMeat(priceList); selectFish(priceList); selectDrink(priceList); return priceList; } /** * 購入する野菜を選択し、金額を追加します。 * 800円・700円・500円の野菜を追加します。 * * @param priceList 購入する商品の金額を格納するリスト */ public void selectVegetables(List<Integer> priceList) { priceList.add(800); priceList.add(700); priceList.add(500); } /** * 購入するお肉を選択し、金額を追加します。 * 1800円の肉を3種類追加します。 * * @param priceList 購入する商品の金額を格納するリスト */ public void selectMeat(List<Integer> priceList) { priceList.add(1800); priceList.add(1800); priceList.add(1800); } /** * 購入する魚を選択し、金額を追加します。 * 650円・400円・500円の魚を追加します。 * * @param priceList 購入する商品の金額を格納するリスト */ public void selectFish(List<Integer> priceList) { priceList.add(650); priceList.add(400); priceList.add(500); } /** * 購入する飲み物を選択し、金額を追加します。 * 100円・80円・50円の飲み物を追加します。 * * @param priceList 購入する商品の金額を格納するリスト */ public void selectDrink(List<Integer> priceList) { priceList.add(100); priceList.add(80); priceList.add(50); } /** * 立ち読みします。 * */ public void read() { } }

Copyright © Xincor miXell Co., Ltd. All rights reserved

results matching ""

    No results matching ""