5-3.クラス-抽象クラス
はじめに
5-3-1、5-3-2で作成するプログラム(演習課題も含む)を保存するためのパッケージを作成する。
5-3-3で作成するプログラム(演習課題も含む)を保存するためのパッケージを作成する。
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 (情報表示) |
以下の情報を表示 親クラスの情報 盾の守備力 |
以下の情報を表示 親クラスの情報 杖の魔力 |
【共通フィールド・メソッド】
【実装手順】
- 1次職の抽象クラスを作成し、共通フィールドとメソッドを定義する。
- ここでは、作成した抽象クラスを『1次職抽象クラス』と呼ぶ。
Fighterクラス・Magicianクラスは1次職抽象クラスを継承する。
- 実装クラス(Fighterクラス・Magicianクラス)から、1次職抽象クラスにまとめた個所を除外する。
- 実装クラス(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次職抽象クラス作成に伴う変更内容
- AxMaster・LanceMaster・SwordMasterは、2次職抽象クラスを extends し、IFighterSecondJob を implements しない。
- AxMaster・LanceMaster・SwordMasterは、2次職抽象クラスの extends に伴い、ソースコードを整理する。
- 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.購入商品の金額計算
2.帰宅
購入商品の金額計算メソッド
- 購入する商品を選択する(商品の金額を格納する)。
- 野菜選択メソッドを実行する。
- 肉選択メソッドを実行する。
- 魚選択メソッドを実行する。
- 飲み物選択メソッドを実行する。
- 商品の合計金額を算出する。
- ポイント数を算出する。
- 合計金額および、ポイント数を表示する。
帰宅メソッド
空でよい。
<学生クラス>
機能の表示・選択メソッド
使用できる機能を以下のように一覧表示し、入力された番号を読み取る。
画面レイアウト
使用する機能を選択してください。
※先頭の数字を入力してください。
1.購入商品の金額計算
2.立ち読み
購入商品の金額計算メソッド
- 購入する商品を選択する(商品の金額を格納する)。
- 野菜選択メソッドを実行する。
- 肉選択メソッドを実行する。
- 魚選択メソッドを実行する。
- 飲み物選択メソッドを実行する。
- 商品の合計金額を算出する。
- ポイント数を算出する。
- 合計金額および、ポイント数を表示する。
立ち読みメソッド
空でよい。
【テストパターン】
考え方
・仕様通りに動作する。
・表示された番号以外を入力する。
未入力、数値でないもの(文字や記号)、表示された番号以外の数字
【既存ソースファイル】
以下実行クラス~学生クラス一式
必要なソースコード一式:右クリック⇒名前を付けてリンク先を保存
【実行クラス】
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