継承とは

既にあるクラスの機能を引き継いで、新しいクラスを作成する方法を継承(inheritance) といいます。元となるクラスのことをスーパークラスといい、引き継ぐ新しい子クラスをサブクラスといいます。サブクラスはスーパークラスのメソッドが引き継げます。

継承の例

つぎの例は、スーパークラス「キャラクター」を継承して「ウィザード」「ウォリアー」を定義したものです。スーパークラスの機能がそのままで、データを設定したり、新たに機能を追加できます。

  • サブクラスは、スーパークラスからプロパティやメソッドを引き継ぐ
  • サブクラスは、新たにプロパティやメソッドを定義できる
  • サブクラスは、スーパークラスのプロパティやメソッドを上書きできる

extends

サブクラス(子クラス)がスーパークラス(親クラス)を継承するには、extendsを利用します。サブクラスが継承すると、スーパークラスの機能を利用できます。

修飾子 class サブクラス extends スーパークラス {

}

継承(extends)の例

スーパークラスをCharacterとします。

スーパークラス(親クラス)
public class Character {

}

サブクラスWizardCharacterを継承した場合で、extendsを利用します。

サブクラス(子クラス)
public class Wizard extends Character {

}

スーパークラス

スーパークラスとは

クラスには「継承」という仕様があり、クラスを親子関係とした階層構造にすることができます。スーパークラスは、クラス階層で上位のクラスで、Javaでの最上位のクラス(トップレベルクラス)はObjectクラスです。

super()メソッド

super() は、スーパークラスのコンストラクタを実行するメソッドです。上位クラス(サブクラス)の指定がない場合は、Objectクラスのコンストラクタが実行されます。

super();

スーパークラス

public class スーパークラス {

    public コンストラクタ(引数) {

    }

}

サブクラス

public class サブクラス {

    public コンストラクタ(引数) {
        //スーパークラスのコンストラクタ実行
	    super(引数);
    }

}

サブクラスの作成

ファイル構成

src/rpg/
├── App2.java
├── Character.java
├── Monster
├── Wizard.java
└── Warrior.java

スーパークラスの修正

Characterにフィールドに「mp」「level」「exp」「attackPower」「defencePower」を追加します。

Character.java
public class Character {

	public String name;
	public String job;
	public int hp;
	public int mp;
    public int level;
    public int exp;
	public int attackPower;
	public int defencePower;

    ...
}

スーパークラス修正

スーパークラスにコンストラクタ追加

Characterクラスに、サブクラスに対応したコンストラクタを追加します。

引数指定

引数はnameのみとします。

コンストラクタが追加されました。

Character.java
public class Character {
    //引数が name のコンストラクタ追加
	public Character(String name) {
		this.name = name;
	}

	public Character(String name, String job) {
		System.out.println("キャラクタ新規作成");
		this.name = name;
		this.job = job;
		this.hp = 50;
	}

    ...
}

フィールド値設定

Characterクラスのコンストラクタで、levelexpなどの値を初期化します。

Character.java
	public Character(String name) {
		this.name = name;
		this.level = 1;
		this.exp = 0;
	}

サブクラスの作成

Wizardクラス作成

Wizardクラスを作成し、Characterクラスをextendsで継承します。

public class Wizard extends Character {
    ....
}

Characterクラスを継承するとコンパイルエラーになります。これは、Characterクラスにコンストラクタがある場合、サブクラスもコンストラクタの実装が必要です。

サブクラスにコンストラクタ追加

VSCodeのクイックフィックスで、コンストラクタを追加します。今回はString nameが引数のコンストラクタを利用します。

Wizardクラスにコンストラクタが追加されました。

Wizard.java
    public Wizard(String name) {
        super(name);
    }

Wizardクラスのコンストラクタに、任意のステータスを設定します。これでサブクラスを作成することで、特有のキャラクターが作成できます。

Wizard.java
package rpg;

public class Wizard extends Character {

    public Wizard(String name) {
        super(name);
        this.job = "wizard";
        this.hp = 30;
        this.mp = 20;
        this.attackPower = 3;
        this.defencePower = 3;
    }
    
}

Warriorクラス作成

同様にサブクラスWarriorも作成します。

Warrior.java
package rpg;

public class Warrior extends Character {

    public Warrior(String name) {
        super(name);
        this.job = "warrior";
        this.hp = 50;
        this.mp = 0;
        this.attackPower = 7;
        this.defencePower = 3;
    }
    
}

メソッドの追加

Character
	public void attack(Character character) {
		int damage = 5;
		character.hp -= damage;
	}

メインプログラムの実行

インスタンス生成

メインプログラムApp2のメインメソッドに、WizardWarriorインスタンスを作成します。

App2.java
package rpg;

public class App2 {

	public static void main(String[] args) {
		Wizard wizard = new Wizard("アリス");
		Warrior warrior = new Warrior("ボブ");
	}

}
  • コンストラクタの引数はname

メソッド実行

talk() メソッドを実行します。

App2.java
    public static void main(String[] args) {
        Wizard wizard = new Wizard("アリス");
        Warrior warrior = new Warrior("ボブ");
        wizard.talk(warrior, "こんにちは!");
    }

スーパークラスCharactertalk() メソッドが実行されました。

結果
ボブ!こんにちは!

メソッドの修正

Monsterの作成

Monsterクラスを作成し、Characterクラスと同様のフィールドとメソッドを追加します。

Monster.java
package rpg;

public class Monster {

	public String name;
	public int hp;
	public int mp;
	public int attackPower;
	public int defencePower;

	public Monster() {
		this.name = "スライム";
		this.hp = 5;
		this.mp = 0;
		this.attackPower = 2;
		this.defencePower = 1;
	}

	public void attack(Character character) {
		int damage = this.attackPower - character.defencePower;
		if (damage > 0) character.hp -= damage;
	}
}

attack() のオーバーロード

メソッド追加

Characterクラスに オーバーロードメソッドattack() を追加します。

Character.java
public class Character {
	...
    // オーバーロードメソッド attack() 追加
	public void attack(Monster monster) {
		int damage = this.attackPower - monster.defencePower;
        if (damage > 0) monster.hp -= damage;
	}
    ...
}

演習

問題1

つぎの「Animal」クラスをスーパークラスとして、サブクラス「Dog」と「Cat」を作成してみましょう。

package zoo;

public class Animal {

	public String type;
	public String name;
	public String crying;
	
	public Animal(String name) {
		super();
        this.name = name;
	}

	public void walk() {
		String message = this.name + "が歩いた";
		System.out.println(message);
	}

	public void cry() {
		System.out.println(this.crying);
	}

	public void escape() {
		String message = this.name + "が逃げた";
		System.out.println(message);
	}
}

問題2

作成した「Dog」「Cat」クラスを使って、メインプログラムでwalk() メソッドを実行してみましょう。

問題3

作成した「Dog」「Cat」クラスを使って、メインプログラムでcry() メソッドを実行してみましょう。