Java入門 #21 - 継承(extends)の基本

入門 | 10分 で読める | 2026.05.02

公式ドキュメント

この記事の要点

継承は既存クラスを拡張して新しいクラスを作る仕組み
extends でスーパークラスを指定、super() でコンストラクタ呼び出し
@Override でメソッドを上書きし、独自の振る舞いを追加

このシリーズについて

「Java入門」シリーズの第21回です。本記事では**継承(Inheritance)**の基本を学びます。

前提条件: #12 - クラスの基本#13 - コンストラクタとメソッド を理解していること。

継承とは

継承は、既存のクラス(スーパークラス / 親クラス)の機能を引き継いで、新しいクラス(サブクラス / 子クラス)を定義する仕組みです。

// Java 21 - スーパークラス
public class Animal {
    protected String name;

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

    public void eat() {
        System.out.println(name + " is eating.");
    }
}
// Java 21 - サブクラス
public class Dog extends Animal {
    public Dog(String name) {
        super(name); // スーパークラスのコンストラクタを呼び出す
    }

    public void bark() {
        System.out.println(name + " is barking: Woof!");
    }
}

DogAnimal を継承しているため、eat() メソッドと name フィールドを持ちます。さらに独自の bark() を追加しています。

ポイント: 継承を使うと、共通の機能を親クラスにまとめ、個別の機能だけを子クラスに追加できます。コードの重複を減らし、保守性が向上します。

extends キーワード

サブクラスを定義するには extends を使います。

public class サブクラス extends スーパークラス {
    // フィールド、コンストラクタ、メソッド
}
用語意味
スーパークラス(親クラス)継承元のクラス
サブクラス(子クラス)継承先のクラス。スーパークラスの機能 + 独自の機能を持つ

Java は単一継承のみサポートします。複数のクラスを同時に継承(extends A, B)することはできません。

注意: Java では1つのクラスしか継承できませんが、後に学ぶ インターフェース(interface)は複数実装できます。

super() でスーパークラスのコンストラクタを呼び出す

サブクラスのコンストラクタは、最初にスーパークラスのコンストラクタを呼び出す必要があります。

// Java 21 - super() の明示的な呼び出し
public class Cat extends Animal {
    private int lives;

    public Cat(String name, int lives) {
        super(name); // Animal のコンストラクタを呼び出す
        this.lives = lives;
    }

    public void meow() {
        System.out.println(name + " is meowing: Meow!");
    }
}

super(name)コンストラクタの最初の行に書く必要があります。書かない場合、コンパイラが自動で super() (引数なし)を挿入しますが、スーパークラスに引数なしコンストラクタがないとコンパイルエラーになります。

ヒント: super() はスーパークラスのコンストラクタ、this() は同じクラスの別のコンストラクタを呼び出します。どちらも最初の行に書く必要があるため、両方を同時に使うことはできません。

フィールド・メソッドの継承

サブクラスはスーパークラスの public / protected フィールドとメソッドを自動的に持ちます。

// Java 21 - 継承されたメソッドを使う例
public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog("Pochi");
        dog.eat();  // Animal から継承したメソッド
        dog.bark(); // Dog 独自のメソッド
    }
}

実行結果:

Pochi is eating.
Pochi is barking: Woof!

Dog クラスには eat() の定義はありませんが、Animal を継承しているため呼び出せます。

メソッドオーバーライド

サブクラスでスーパークラスのメソッドを**上書き(Override)**することができます。

// Java 21 - メソッドオーバーライドの例
public class Bird extends Animal {
    public Bird(String name) {
        super(name);
    }

    @Override
    public void eat() {
        System.out.println(name + " is pecking seeds.");
    }

    public void fly() {
        System.out.println(name + " is flying.");
    }
}

Birdeat()Animaleat() を上書きしています。@Override アノテーションを付けることで、オーバーライドの意図を明示し、コンパイラがチェックしてくれます。

ポイント: @Override は省略可能ですが、必ず付けましょう。メソッド名のタイポ(eat のつもりで eatt と書いてしまう等)をコンパイル時に検出できます。

オーバーライドのルール

ルール説明
メソッド名・引数が同じ異なるとオーバーロード(別メソッド扱い)
戻り値の型は同じか、共変戻り値を子クラスの型に変更するのは許可(共変戻り値型)
アクセス修飾子は同等以上protected → public は OK。public → private は NG
static / final メソッドは不可static は継承しない。final は上書き禁止

アクセス修飾子と継承の関係

スーパークラスのフィールド・メソッドがサブクラスから見えるかどうかは、アクセス修飾子で決まります。

修飾子同じクラス同じパッケージサブクラス(別パッケージ)外部
private
(なし / package-private)
protected
public

継承で重要なポイント:

  • private フィールド・メソッドはサブクラスから直接アクセスできない(継承はされているが見えない)
  • protected はサブクラスからアクセスできるが、外部には非公開
  • public はどこからでもアクセス可能
// Java 21 - アクセス修飾子の違い
public class Animal {
    private String secret = "秘密";       // サブクラスから見えない
    protected String name;                 // サブクラスから見える
    public void eat() { /* ... */ }       // どこからでも呼べる
}

public class Dog extends Animal {
    public void printInfo() {
        // System.out.println(secret); // コンパイルエラー(private)
        System.out.println(name);       // OK(protected)
    }
}

注意: protected は同じパッケージ内からもアクセスできます。完全に継承先だけに公開したい場合でも、パッケージを分けない限り他のクラスから見えてしまいます。

実行例:Animal → Dog の継承

// Java 21 - 継承の動作確認
public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog("Shiba");
        dog.eat();  // Animal から継承
        dog.bark(); // Dog 独自

        Bird bird = new Bird("Sparrow");
        bird.eat();  // Bird でオーバーライド
        bird.fly();  // Bird 独自
    }
}

実行結果:

Shiba is eating.
Shiba is barking: Woof!
Sparrow is pecking seeds.
Sparrow is flying.

Birdeat() はオーバーライドされているため、Animal の実装ではなく Bird の実装が呼ばれます。

super でスーパークラスのメソッドを呼び出す

オーバーライドしたメソッドの中で、スーパークラスの元の実装を呼び出すこともできます。

// Java 21 - super でスーパークラスのメソッドを再利用
public class Bird extends Animal {
    public Bird(String name) {
        super(name);
    }

    @Override
    public void eat() {
        super.eat(); // Animal の eat() を呼び出す
        System.out.println("  (pecking seeds)");
    }
}

実行結果:

Sparrow is eating.
  (pecking seeds)

super.eat() で親の処理を実行してから、追加のメッセージを出力しています。

ヒント: super はフィールドアクセスにも使えます。super.name でスーパークラスの name を明示的に参照できます(ただし同名フィールドを子で再定義するのは混乱の元なので避けましょう)。

プログラミングのベストプラクティス

やるべきこと理由
@Override を必ず付けるタイポや引数ミスをコンパイル時に検出
protected を適切に使うサブクラスにのみ公開したいフィールド・メソッド
継承は「is-a 関係」のときだけDog is an Animal → 自然。Car is an Engine → 不自然(コンポジションを使う)
深い継承階層を避ける3階層以上になると理解困難。設計を見直す

注意: 継承は強力ですが、使いすぎると密結合になります。「コードの再利用」だけが目的なら、後に学ぶ コンポジション(has-a 関係)や インターフェース の方が適切なケースも多いです。

次のステップ

次回以降では以下のトピックを扱います。

  • ポリモーフィズム: Animal animal = new Dog(); のようなアップキャスト
  • abstract クラス: 抽象メソッドを持つクラス
  • インターフェース: 複数実装可能な型の契約

Java入門 #22 - ポリモーフィズムとアップキャスト(今後追加予定)

参考リソース

この技術を体系的に学びたいですか?

未来学では東証プライム上場企業のITエンジニアが24時間サポート。月額24,800円から、退会金0円のオンラインIT塾です。

メールで無料相談する
← 一覧に戻る