20.

super

編集

本稿は Java の super キーワードに関する記事です。super「親クラス (スーパークラス) を指す参照」で、継承関係にあるクラスから親のフィールド・メソッド・コンストラクタにアクセスするために使います。

super の主な用途

用途概要
親クラスのコンストラクタ呼び出しsuper(...)
オーバーライドした親メソッドを呼び出すsuper.method()
シャドーイングされた親フィールド参照super.field
ジェネリクスの境界 (記述子)<? super T> (型システム上の意味)

1. 親クラスのコンストラクタを呼び出す

public class Animal {
    protected final String name;

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

public class Dog extends Animal {
    private final String breed;

    public Dog(String name, String breed) {
        super(name);  // 親のコンストラクタを呼ぶ
        this.breed = breed;
    }
}

サブクラスのコンストラクタからは、最初に親のコンストラクタが必ず呼ばれます。明示的に super(...) を書かない場合、コンパイラが暗黙のうちに super() (引数なし) を呼びます。親に引数なしコンストラクタが無いとコンパイルエラーになります。

2. オーバーライドした親メソッドを呼び出す

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

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

new Dog().greet(); // "hello, woof!"

サブクラスでオーバーライドした親の実装にも一度寄り道してから処理を続けたいときに使います。@Override + super.method() は典型的な「親の動作を拡張する」パターンです。

3. 親クラスのフィールドへアクセス

public class Parent {
    protected int x = 1;
}

public class Child extends Parent {
    protected int x = 2;  // フィールド名が衝突

    public void show() {
        System.out.println(this.x);  // 2 (Child の x)
        System.out.println(super.x); // 1 (Parent の x)
    }
}

ただしフィールドのシャドーイングは混乱の元です。実務では避け、必要なら別名にするのが安全です。

4. ジェネリクスの ? super T

// PECS: Producer Extends, Consumer Super
List<? super Integer> list = new ArrayList<Number>();
list.add(1);    // Integer 以上を受け取れる Consumer 用ワイルドカード

ここでの super はインスタンスへのアクセスではなく、ジェネリクスの型境界 (Consumer 側) を表す記号です。PECS の原則: 取り出すなら ? extends T、書き込むなら ? super T

this と super の使い分け

キーワード指す対象典型用途
this現在のインスタンス自身シャドーイング解消・コンストラクタ間呼出・自身を返す
super親クラス側の実装親コンストラクタ呼出・親メソッド/フィールド参照

注意点

  • super(...) はコンストラクタ本体の先頭でのみ呼べるthis(...) と同時には使えない
  • 親クラスに引数なしのコンストラクタが無いなら、子側で 必ず明示的に super(...) を呼ぶ
  • super1 階層上の親を指す。祖父母クラスへ直接アクセスはできない
  • インタフェースのdefault メソッドを呼ぶには InterfaceName.super.method() という特殊構文を使う
  • 静的 (static) コンテキストでは this 同様に使えない
  • 過度な継承は密結合を生む。継承より合成 (Composition over Inheritance) の検討も

関連

編集
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. ラムダ式