18.

Javaのオーバーライド

編集

オーバーライドとは

オーバーライド (Override) とは、親クラスのメソッドを子クラスで定義し直すことを指します。「親クラスの処理を一部だけ独自に差し替えたい」ときに使い、Java の多態性 (ポリモーフィズム) を実現する中心的な仕組みです。

public class Animal {
    public String greet() { return "hello"; }
}

public class Dog extends Animal {
    @Override
    public String greet() {
        return "woof!";
    }
}

Animal a = new Dog();
a.greet();  // "woof!" (Dog のメソッドが呼ばれる)

オーバーライドの条件

  • メソッドシグネチャが親と同じ (名前・引数の数と型)
  • 戻り値の型は親と同じか、共変な (より狭い) 型でも可
  • アクセス修飾子は親と同等以上の公開度 (狭めるのは不可)
  • throws するチェック例外は親の宣言以下でなければならない
  • static メソッドはオーバーライドできず、隠蔽 (Hide) になる
  • private / final メソッドはオーバーライド不可

@Override アノテーション

@Override を付けると、コンパイラが「親に同じシグネチャのメソッドが本当にあるか」をチェックしてくれます。タイプミスや親の API 変更による事故を防ぐため、オーバーライド時は必ず付けるのが現代の Java の鉄則です。

@Override
public String toString() {
    return "Dog: " + name;
}

親メソッドの結果を利用するパターン

親の処理を完全に置き換えるのではなく、親の結果を呼んでから差分処理するには super.メソッド() を使います。

@Override
public String greet() {
    return super.greet() + ", woof!";
}

オーバーライドの禁止 (final)

親クラスのメソッドに final 修飾子を付与すると、子クラスでオーバーライドできなくなります。これは「変えてはいけない振る舞い」を強制する手段として有効です。

public class Base {
    public final void run() {
        // 子クラスで override 不可
    }
}

クラス自体に final を付与すれば、そもそも継承自体を禁止できます (java.lang.String など)。

オーバーライドとオーバーロードの違い

項目オーバーライドオーバーロード
関係親 → 子のクラス間同一クラス内 (継承下でも可)
シグネチャ親と同一引数の数・型・順序が違う
ディスパッチ動的 (実行時の実型)静的 (コンパイル時)
典型用途多態性・振る舞いの差し替え同名メソッドの便利な集約

詳しくは オーバーロード も参照。

典型的なオーバーライド対象

メソッド用途
toString()デバッグ・ログでのオブジェクト表示
equals(Object) / hashCode()等価判定・Set / Map のキー用 (セットで実装)
compareTo(T)ソート (Comparable)
Object.clone()複製 (使用は慎重に)
抽象クラス・インタフェースのメソッド実装の提供 (実質的にオーバーライド)

動的ディスパッチ (多態性) の例

List<Animal> animals = List.of(new Dog(), new Cat(), new Animal());
for (Animal a : animals) {
    System.out.println(a.greet());
    // 各インスタンス本来の greet() が呼ばれる
}

注意点

  • @Override を必ず付ける。シグネチャ違いをコンパイラに検出させる
  • equals と hashCode はセットでオーバーライド。一方だけ変えると Set / Map で破綻する
  • 戻り値型・スローする例外を狭めるのは OK、広げるのは NG
  • アクセス修飾子を狭めるのは不可 (publicprotected はエラー)
  • static メソッドの「オーバーライド」と見えるものは隠蔽 (Hiding)。実行時の型ではなく宣言時の型で選ばれる
  • コンストラクタは継承されず、オーバーライドの対象ではない
  • 子クラスでのオーバーライド時、親が呼ばれなくなる副作用を見落とさない (テンプレートメソッドの破壊)

関連

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. 基本的なルール
  2. データ型
  3. 変数
  4. 定数
  5. 配列
  6. コレクション(List,Set,Queue)
  7. Map(連想配列)
  8. 演算子
  9. 条件分岐
  10. 繰り返し制御文
  11. クラス
  12. メソッド
  13. インスタンス化
  14. コンストラクタ
  15. staticキーワード
  16. オーバーロード
  17. 継承
  18. オーバーライド
  19. this
  20. super
  21. パッケージ
  22. アクセス修飾子
  23. 抽象クラス・メソッド
  24. インターフェース
  25. カプセル化
  26. データベース接続
  27. セッション
  28. ファイル入出力
  29. ラムダ式