TL;DR

既存のクラスの属性や振る舞いを新しいクラスに引き継ぎ、機能を追加・変更できるようにするしくみである。引き継ぐ側をサブクラス(子クラス)、引き継がれる側をスーパークラス(親クラス)と呼ぶ。

なぜ必要か

作りたいクラスのコードの一部を持つクラスがすでにあれば、そこから新しいクラスを派生させて、既存のフィールドやメソッドを書き直さずに再利用できる。クラスの間に階層ができるので、多態性を使って異なるクラスを同じように扱える。

仕組み

Java のチュートリアルによると、サブクラスはスーパークラスのメンバ(フィールド、メソッド、ネストしたクラス)をすべて継承する。コンストラクタはメンバではないので継承されないが、サブクラスから super(...) で呼び出せる。Java では、Object 以外のすべてのクラスは直接のスーパークラスを 1 つだけ持つ(単一継承)。

例

public class MountainBike extends Bicycle {
    public int seatHeight;
 
    public MountainBike(int startHeight, int startCadence,
                        int startSpeed, int startGear) {
        super(startCadence, startSpeed, startGear);
        seatHeight = startHeight;
    }
 
    public void setHeight(int newValue) {
        seatHeight = newValue;
    }
}

MountainBike は Bicycle のフィールドとメソッドをすべて継承し、seatHeight フィールドとそれを設定するメソッドを足している。

注意点

複数のスーパークラスを持つ多重継承では、どのメンバが参照されるのかを把握しにくくなる。そのため Java や C# は、クラスの継承を単一継承に限り、インタフェースは複数実装できるようにしている。

差分だけを書く目的で継承を使うと、データとメソッドが階層に散らばって把握しにくくなる。代わりに合成(コンポジション)が重視されるようになっている。テスト駆動開発(書籍) でも、一般には継承より委譲と言われることに触れている。

関連

出典