Javaの継承
継承の基本
継承は、既存のクラス(親クラスまたはスーパークラス)の特性(フィールドとメソッド)を新しいクラス(子クラスまたはサブクラス)に引き継ぐ仕組みです。
子クラスは親クラスの特性を継承し、必要に応じて拡張または変更できマス。
継承の宣言
Javaで継承を宣言するには、以下のように子クラスを親クラスに拡張するキーワード extends
を使用します。
class スーパークラス {
// フィールド
// コンストラクタ
// メソッド
}
class サブクラス extends スーパークラス {
// フィールド
// コンストラクタ
// メソッド
}
上記のコードでは、サブクラスはスーパークラスを継承しています。
サブクラスは、スーパークラスのフィールド、メソッド、コンストラクタをそのまま使用できます。
- サブクラスは、スーパークラスのメンバにアクセスできますが、アクセス修飾子によって制限される場合があります。
public
やprotected
ならアクセスできますが、private
ならアクセスできません。 - サブクラスのコンストラクタでは、最初に
super()
メソッドを呼び出して、スーパークラスのコンストラクタを実行すします。
引数がある場合は、super(引数)
と記述します。
省略した場合、引数なしのコンストラクタが内部的に自動で呼び出されます。
継承の例
以下は、継承の例です。
// スーパークラス
class Human {
public String name;
public Human(String name) {
this.name = name;
}
public void introduce() {
System.out.println("私は、" + name + "です。");
}
}
// サブクラス
class Werewolf extends Human {
public Werewolf(String name) {
super(name);
}
public void transform() {
System.out.println("ガオーン! 狼男に変身!");
}
}
// サブクラス
class Knight extends Human {
public Knight(String name) {
super(name);
}
public void fight() {
System.out.println("騎士の剣で戦います!");
}
}
// サブクラスの使用例
Werewolf werewolf = new Werewolf("リアル");
werewolf.introduce(); // 私は、リアルです。
werewolf.transform(); // ガオーン! 狼男に変身!
Knight knight = new Knight("アーサー");
knight.introduce(); // 私は、アーサーです。
knight.fight(); // 騎士の剣で戦います!
・このコードでは、Human
というスーパークラスがあり、そのサブクラスとしてWerewolf
(狼男)とKnight
(騎士)があります。
・狼男は変身することができ、騎士は戦うことができます。
これらのメソッドは、それぞれのサブクラスで定義されています。
・そして、すべてのキャラクターは自己紹介をすることができます。
これはスーパークラスであるHuman
で定義されているメソッドです。
このように、Javaの継承を利用することで、共通の機能をスーパークラスにまとめ、個別の機能をサブクラスで定義することが可能です。
コードの重複を避けることができ、効率的なプログラミングが可能になります。
また、サブクラスは必要に応じてスーパークラスのメソッドをオーバーライド(上書き)することも可能です。
これにより、同じメソッド名でもサブクラスごとに異なる動作をさせることができます。
メソッドのオーバーライド
メソッドのオーバーライドは、親クラスに定義されたメソッドを子クラスで同じ名前のメソッドで再定義することです。
これにより、子クラスのインスタンスが親クラスのメソッドを呼び出したときに、子クラスで定義したメソッドが優先的に実行されます。
オーバーライドの基本構文
オーバーライドするには、スーパークラスのメソッドと同じ名前、引数、戻り型のメソッドをサブクラスで定義します。
class スーパークラス {
public void メソッド名(引数) {
// メソッドの処理
}
}
class サブクラス extends スーパークラス {
@Override
public void メソッド名(引数) {
// メソッドの処理を拡張または変更
}
}
上記のコードでは、スーパークラス
のメソッド名()
メソッドをサブクラス
でオーバーライドしています。
メソッドのオーバーライドをするためには、以下の条件を満たす必要があります。
・メソッド名が親クラスと子クラスで同じであること
・引数の個数や型が親クラスと子クラスで同じであること
・戻り値の型が親クラスと子クラスで同じか、親クラスの戻り値の型のサブタイプであること。
・アクセス修飾子が親クラスと子クラスで同じか、より広い範囲になっていること(狭くなっている場合はエラーになる)
メソッドのオーバーライドをする際には、@Overrideアノテーションをメソッドの上に付けることが推奨されます。
これは、コンパイラにオーバーライドを意図していることを伝えるためです。
もしメソッドの名が違っているとエラーになるので、ミスを軽減できます。
「継承の例」のコードにKnightを継承した聖騎士クラスを追加すると、以下のようになります。
聖騎士クラス
class HolyKnight extends Knight {
public HolyKnight(String name) {
super(name);
}
@Override
public void introduce() {
System.out.println("我は" + name + "なり!聖なる光を放て!");
}
}
このコードでは、Knight
クラスを継承したHolyKnight
クラスを定義しています。HolyKnight
クラスでは、Knight
クラスのintroduce()
メソッドをオーバーライドして、以下のように変更しています。
public void introduce() {
System.out.println("我は" + name + "なり!聖なる光を放て!");
}
この変更により、HolyKnight
オブジェクトのintroduce()
メソッドを呼び出すと、以下のように出力されます。
我はランスロットなり!聖なる光を放て!
また、introduce()
メソッドに聖なる光
を追加することで、聖騎士らしい雰囲気を表現しています。
修正後のコード
// スーパークラス
class Human {
public String name;
public Human(String name) {
this.name = name;
}
public void introduce() {
System.out.println("私は、" + name + "です。");
}
}
// サブクラス
class Werewolf extends Human {
public Werewolf(String name) {
super(name);
}
public void transform() {
System.out.println("ガオーン! 狼男に変身!");
}
}
// サブクラス
class Knight extends Human {
public Knight(String name) {
super(name);
}
public void fight() {
System.out.println("騎士の剣で戦います!");
}
}
// サブクラス
class HolyKnight extends Knight {
public HolyKnight(String name) {
super(name);
}
@Override
public void introduce() {
System.out.println("我は" + name + "なり!聖なる光を放て!");
}
}
// サブクラスの使用例
Werewolf werewolf = new Werewolf("リアル");
werewolf.introduce(); // 私は、リアルです。
werewolf.transform(); // ガオーン! 狼男に変身!
Knight knight = new Knight("アーサー");
knight.introduce(); // 私は、アーサーです。
knight.fight(); // 騎士の剣で戦います!
HolyKnight holyknight = new HolyKnight("ランスロット");
holyknight.introduce(); // 我はランスロットなり!聖なる光を放て!
聖騎士の能力や、introduce()
メソッドに追加する内容は、自由に変更することができます。
※サブクラスは、自分自身のメソッドやオーバーライドしたメソッド内で、super.メソッド名()
と記述することで、スーパークラスのメソッドを呼び出すことができます。
項目 | 説明 |
---|---|
継承 | あるクラスの機能を、別のクラスに引き継ぐ機能 |
継承の宣言 | class サブクラス extends スーパークラス {} |
継承のメリット | コードの再利用性を高めることができる、親子関係を表現することができる |
継承の注意点 | スーパークラスのフィールドやメソッドは、サブクラスでも使用できる、サブクラスでスーパークラスのメソッドをオーバーライドすると、サブクラスのメソッドが呼び出される |