BLOG

【プログラマー研修 Java】カヤの記録2

こんにちは、カヤです!

寒い日が続いていますが、みなさん体調は崩していませんか?
先日のお休みの日はあったか~い部屋で
あったか~い鍋を突いていました。
厳しい寒さはまだまだ続きますので、
風邪並びに感染症対策をきっちりして
気を引き締めていきましょう!

さて、肝心のJava研修ですが、
クラスの使い方を淡々と進めています。
今回は抽象クラスについて学びました。

●抽象クラス

クラス宣言時に「abstract」を付けて宣言します。
また、クラス内に「abstract」を付けたメソッドを用意する必要があります。
これを抽象メソッド呼び、抽象クラス内では実装を行いません。
抽象メソッドは抽象クラスを継承したクラスで実装を行います。

/* 抽象クラス */
abstract class AbstractClass {

	/* 抽象メソッド */
	abstract void abstractMethod(int num);
}

/* サブクラス(抽象クラスを継承) */
class SubClass extends AbstractClass{

	/* 抽象メソッドをオーバーライドして実装を行う */
	@Override
	void abstractMethod(int num) {
		// TODO 自動生成されたメソッド・スタブ	
	}
}

void abstractMethod(int num)が継承したクラスにない場合は、
コンパイル時にエラーになるので注意!
また、抽象クラス自体は実装のない抽象メソッドを持っている為、
直接newを使用してインスタンス化することができません。

同じゲーム内のキャラクターで
セリフの内容が違うからと言ってそれぞれ別名のメソッドを作るのではなく、
同じセリフメソッドで共通にしてしまおう!
みたいな使い方ができるわけです。
実際にコードを書いてみましょう!

●使用例

抽象クラスであるキャラクタークラスを定義しました。
キャラクタークラスには、職業と名前のフィールドを用意。
抽象クラスに忘れてはならないのが抽象メソッドで、
キャラクター特有でセリフを出力させる「セリフメソッド」を用意しました。

/* キャラクタークラス */
abstract class Character{
	protected String job;		// 職種
	protected String name;		// 名前

	/* コンストラクタ */
	public Character(String job, String name) {
		this.job = job;
		this.name = name;
	}

	/* セリフメソッド */
	// 抽象メソッド
	abstract public void Serif();
}

このキャラクタークラスを継承させた兵士クラスを作ります。
兵士クラスのコンストラクタでは、
スーパークラスであるキャラクタークラスのコンストラクタを呼び出しています。
キャラクタークラスを継承した兵士クラスはセリフメソッドで特有の処理を実装できます。
セリフメソッドでは自身のフィールドの職種と名前を使用して独自のセリフを標準出力。

/* 兵士クラス */
class Warrior extends Character{

	/* コンストラクタ */
	public Warrior(String name) {

		// 抽象クラスのコンストラクタ
		super("へいし", name);
	}

	/* セリフメソッド */
	@Override
	public void serif() {

		// 職種と名前の表示
		System.out.println(
				"われは " + this.job + " の " + this.name + " だ。");
	}
}

ソースコードの全体は下記のようになりました。
mainメソッドで作ったクラスをインスタンス化、セリフの表示を行います。
兵士クラスに合わせて魔法使いクラスも用意。

package sample;

public class Serif {

	public static void main(String[] args) {

		Warrior warrior = new Warrior("カヤ");
		Wizard wizard = new Wizard("かや");

		// 戦士の自己紹介&攻撃
		warrior.serif();

		// 改行
		System.out.println();

		// 魔法使いの自己紹介&攻撃
		wizard.serif();
	}

}

/* キャラクタークラス */
abstract class Character{
	protected String job;		// 職種
	protected String name;		// 名前

	/* コンストラクタ */
	public Character(String job, String name) {
		this.job = job;
		this.name = name;
	}

	/* セリフメソッド */
	// 抽象メソッド
	abstract public void serif();
}

/* 兵士クラス */
class Warrior extends Character{

	/* コンストラクタ */
	public Warrior(String name) {

		// 抽象クラスのコンストラクタ
		super("へいし", name);
	}

	/* セリフメソッド */
	@Override
	public void serif() {

		// 職種と名前の表示
		System.out.println(
				"われは " + this.job + " の " + this.name + " だ。");
	}
}

/* 魔法使いクラス */
class Wizard extends Character{

	/* コンストラクタ */
	public Wizard(String name) {

		// 抽象クラスのコンストラクタ
		super("まほうつかい", name);
	}

	/* セリフメソッド */
	@Override
	public void serif() {

		// 職種と名前の表示
		System.out.println(
				"わたしは " + this.job + " の " + this.name + " でございます。");
	}
}

実行結果はこちら

――――――――――――――――――――――
われは へいし の カヤ だ。

わたしは まほうつかい の かや でございます。
――――――――――――――――――――――

抽象クラスを継承した二人のキャラクターが、同じ名前の抽象メソッドで別々のセリフをしゃべりました!

●まとめ

抽象メソッドの約束として…
①必ずオーバーライドするメソッドを用意する(抜け漏れ防止)
②抽象メソッドをすべてオーバーライドする必要がある
③インスタンス化できない
といった感じ。
今回はキャラクターのセリフでしたが、
何かと便利に使えそうです。
やってることは同じだけど、実装は分けたい場面…
皆さんも考えて使ってみましょう!

今回はここまで。
カヤでした!

BLOGトップへ戻る