😸
[Java]クラスの継承
はじめに
ここでは以下についてまとめています。
- クラスの継承
- オーバーライド
super
- 抽象クラス(
abstract
)
クラスの継承
既存のクラス(親クラス/スーパークラス)を拡張して、新しいクラス(子クラス/サブクラス)を作る仕組みです。コードの再利用性や拡張性を高めることができます。
すべてのクラスは、暗黙的にjava.lang.Object
クラスを継承しています。
継承
あるクラスが他のクラスを「継承(inherit)」することで、そのクラスのフィールドやメソッドを引き継ぐことができます。
また、親クラスの機能を再利用・拡張・上書き(オーバーライド)できます。
Javaでは単一継承のみであり、1つのクラスだけ継承可能です。
基本構文
extend
を使用して継承します。
class 親クラス {
// フィールドやメソッド
}
class 子クラス extends 親クラス {
// 継承されたものを使ったり、独自の機能を追加したりできる
}
継承の例
Dog
がAnimal
という親クラスを継承しています。
class Animal {
void speak() {
System.out.println("動物が鳴く");
}
}
class Dog extends Animal {
void wagTail() {
System.out.println("しっぽを振る");
}
}
Dog dog = new Dog();
dog.speak(); // 動物が鳴く(親クラスのメソッド)
dog.wagTail(); // しっぽを振る(子クラスの独自メソッド)
オーバーライド
子クラスが、親クラスのメソッドを上書きして独自の動作に変更できます。
class Animal {
void speak() {
System.out.println("動物が鳴く");
}
}
class Dog extends Animal {
@Override
void speak() {
System.out.println("ワンワン!");
}
void wagTail() {
System.out.println("しっぽを振る");
}
}
以下のようにAnimal animal = new Dog();
とするとanimal.wagTail();
はコンパイルエラーになります。
今回Animal animal = new Dog();
としているのは抽象的に扱いたいためです(ポリモーフィズム)。
wagTail()
を使用したいのであれば、Dog dog = new Dog();
とするとdog.wagTail(); // しっぽを振る
が出力されます。
Animal animal = new Dog();
animal.speak(); // ワンワン!(子クラスの実装が使われる)
animal.wagTail(); // コンパイルエラー:Animal型に wagTail() は存在しない
super
キーワード
super
を使うと、親クラスのコンストラクタやメソッドにアクセスできます。
以下は親クラスのメソッドを呼び出しています。
class Animal {
void speak() {
System.out.println("動物が鳴く");
}
}
class Dog extends Animal {
@Override
void speak() {
super.speak(); // 親の speak を呼ぶ
System.out.println("ワンワン!");
}
}
親クラスのコンストラクタを呼び出す際は以下のようにします。
class Animal {
Animal(String name) {
System.out.println("Animal: " + name);
}
}
class Dog extends Animal {
Dog() {
super("ポチ"); // 親クラスのコンストラクタを呼ぶ
}
}
抽象クラス
共通の機能の定義と、共通インターフェースの提供を目的としたクラス設計の一部です。直接インスタンス化できないクラスで、他のクラスに継承されることを前提としています。
以下のような場合に使用します。
- 共通の機能を定義しつつ、一部の振る舞いはサブクラスに任せたいとき
- ポリモーフィズム(多態性)を活用したいとき
- インターフェースよりも共通実装を多く持たせたいとき
基本構文
abstract
を使用します。
abstract class クラス名 {
// フィールド、コンストラクタ、具象メソッド、抽象メソッドなど
}
抽象クラスの例
abstract class Animal {
// 抽象メソッド(中身なし)
abstract void speak();
// 通常のメソッド(中身あり)
void sleep() {
System.out.println("すやすや眠る");
}
}
// 継承クラス
class Dog extends Animal {
@Override
void speak() {
System.out.println("ワンワン!");
}
}
public class Main {
public static void main(String[] args) {
Animal dog = new Dog();
dog.speak(); // → ワンワン!
dog.sleep(); // → すやすや眠る
}
}
特徴 | 説明 |
---|---|
abstract キーワード |
クラスとメソッドに使う |
インスタンス化不可 |
new Animal() はできない(抽象クラス単体では使えない) |
抽象メソッドを含める | 中身のないメソッドを定義して子クラスに実装を強制 |
通常のメソッドも定義可 | 具象メソッド(sleep など)も持てる |
フィールドやコンストラクタも持てる | 他のクラスと同じように持てる |
子クラスは extends で継承 |
抽象メソッドをすべてオーバーライドする必要あり |
Discussion