🏗️継承: オブジェクト指向の三大要素の一つ

継承は、既存のクラスの機能(フィールドやメソッド)を新しいクラスが引き継ぎ、コードの再利用階層構造の構築を可能にする仕組みです。


🏗️ 1. 継承の基本的な仕組み

定義とキーワード

継承は、親クラス(スーパークラス)の機能を子クラス(サブクラス)が受け継ぐことで成立します。

  • 親クラス (Superclass):機能を提供する元のクラス。
  • 子クラス (Subclass):親クラスの機能を受け継ぎ、新しい機能を追加したり、既存の機能を変更したりするクラス。
  • extends キーワード: Javaで継承を行う際に子クラスの宣言に使用します。

Java

// 親クラス
class Animal {
    String name;
    public void eat() {
        System.out.println(name + "が食事をします。");
    }
}

// 子クラス: Animalを継承する
class Dog extends Animal {
    public void bark() {
        System.out.println(name + "がワンワン吠えます。");
    }
}

継承の効果

  1. 再利用: 子クラスは、親クラスのフィールド(name)やメソッド(eat())を自分で定義することなくそのまま利用できます。
  2. 拡張: 子クラスは、親クラスの機能に加え、独自の機能(bark())を追加できます。

2. 継承のルールと注意点

2.1. 単一継承

  • Javaでは、一つのクラスが直接継承できる親クラスは一つだけです(単一継承)。
    • 複数のクラスから機能を取り込みたい場合は、インターフェース(多重継承に似た仕組み)を利用します。

2.2. アクセス修飾子と継承

  • 親クラスの**publicprotected**な要素は子クラスに継承されます。
  • 親クラスの**privateなフィールドやメソッドは、子クラスから直接アクセスすることはできません**。ただし、親クラスがpublicなゲッター/セッターメソッドを提供していれば、それを介して間接的にアクセスは可能です。

2.3. コンストラクタは継承されない

  • メソッドやフィールドとは異なり、コンストラクタは継承されません
  • 子クラスのコンストラクタ内で、親クラスのコンストラクタを呼び出すには、super()キーワードを使用します。これは、子クラスのコンストラクタの最初の行で呼び出す必要があります。

Java

class Pet extends Animal {
    public Pet(String name) {
        // 親クラス(Animal)のコンストラクタを呼び出す
        super(); 
        this.name = name;
    }
}

3. ポリモーフィズムへの道: メソッドのオーバーライド

継承の最も重要な利用法の一つが、オーバーライド(上書き)を通じたポリモーフィズムの実現です。

  • オーバーライド: 親クラスが定義したメソッドと同じ名前、同じ引数、同じ戻り値のメソッドを、子クラスで改めて定義し直すことです。
  • これにより、子クラスは親クラスから引き継いだメソッドの振る舞いを変えることができます。

Java

// 親クラスのメソッド
class Animal {
    public void cry() {
        System.out.println("動物が鳴きました。"); 
    }
}

// 子クラスでメソッドをオーバーライド
class Cat extends Animal {
    @Override // アノテーションをつけると、オーバーライドのルールをコンパイラがチェックしてくれる
    public void cry() {
        System.out.println("ニャーニャーと鳴きました!"); // 振る舞いを変更
    }
}

この結果、Animal型変数にCatオブジェクトを代入しcry()を呼び出すと、Catのオーバーライドされたメソッドが実行されます(これがポリモーフィズムです)。

継承を使いこなすことで、現実世界の階層的な関係をプログラムで表現し、大規模なシステムを効率よく構築できるようになります。