superキーワード

クラスを継承してサブクラスを定義した場合、サブクラスでは super キーワードを使ってスーパークラスのメソッドやフィールドにアクセスすることができます。また super() を使うことで、サブクラスのコンストラクタからスーパークラスのコンストラクタを呼び出すこともできます。ここではオブジェクト指向における super キーワードの使い方について解説します。

superキーワードとは

クラスを継承した場合、サブクラスはスーパークラスのフィールドやメソッドを引き継いで利用することができます。このとき、スーパークラスのフィールドやメソッドを明示的に指定して利用したい場合に使用するのが super キーワードです。

super は、サブクラスの中でスーパークラスを表すためのキーワードです。 this が現在のオブジェクト自身を表すのに対して、 super はそのオブジェクトのスーパークラスの部分を表します。

※ this キーワードについては「thisキーワード」を参照されてください。

※ super キーワードはこのページで解説している利用方法以外にも、メソッドをオーバーライドした場合にも使用されることがあります。詳しくは「メソッドのオーバーライド」を参照されてください。

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

サブクラスではスーパークラスで定義されているメソッドを引き継いで利用することができますが、 super を使うことでスーパークラスのメソッドを明示的に呼び出すことができます。

class Product {
  private void showData() {
    System.out.println("製品データを表示します");
  }
}

class Foods extends Product {
  private void showFoodData() {
    super.showData();
    System.out.println("食料品データを表示します");
  }
}

この例では Foods クラスの showFoodData メソッドの中で、super.showData() を使ってスーパークラス Product の showData メソッドを呼び出しています。

ただし、サブクラスで同じ名前のメソッド名が定義されていない場合は super は省略して showData() としても呼び出すことはできます。

class Product {
  private void showData() {
    System.out.println("製品データを表示します");
  }
}

class Foods extends Product {
  private void showFoodData() {
    showData();
    System.out.println("食料品データを表示します");
  }
}

スーパークラスのフィールドにアクセスする

スーパークラスのフィールドにアクセスしたい場合にも super を使うことができます。

class Product {
  String name = "製品";
}

class Food extends Product {
  int price = 100;

  public void showName() {
    System.out.println(price);
    System.out.println(super.name);
  }
}

この例では Foods クラスの name フィールドへアクセスするために super.name と記述しています。

ただし、サブクラスで同じ名前のフィールドが定義されていなかったり、メソッド内で同じ変数名が使用されていない場合は super は省略して name でアクセスすることはできます。

class Product {
  String name = "製品";
}

class Food extends Product {
  int price = 100;

  public void showName() {
    System.out.println(price);
    System.out.println(name);
  }
}

なおスーパークラスのフィールドにアクセス修飾子として private が設定されていた場合は、この方法ではアクセスできません。 private が設定されている場合は同じクラス内からしかアクセスできないためです。サブクラスから直接スーパークラスのフィールドへアクセスしたい場合は、今回のようにアクセス修飾子を省略するか protected を設定する必要があります。

コンストラクタでsuperを使う

super はコンストラクタの中でも使用できます。サブクラスのコンストラクタの中で super() を使うと、スーパークラスのコンストラクタを呼び出すことができます。

class Product {
  Product() {
    System.out.println("Productクラスのコンストラクタ");
  }
}

class Foods extends Product {
  Foods() {
    super();
    System.out.println("Foodsクラスのコンストラクタ");
  }
}

この場合、Foods クラスのオブジェクトを作成すると、最初にスーパークラス Product のコンストラクタが呼び出され、その後で Foods クラスのコンストラクタが実行されます。

ただ super() を明示的に記述しなくても、サブクラスのコンストラクタが呼び出されると自動的にコンストラクタの先頭で super() が実行され、スーパークラスのコンストラクタが呼び出されます。

確認のため、下記のような簡単なサンプルを実行してみます。

public class Sample {
  public static void main(String[] args) {
    Foods f = new Foods();
  }
}

class Product {
  Product() {
    System.out.println("Productクラスのコンストラクタ");
  }
}

class Foods extends Product {
  Foods() {
    System.out.println("Foodsクラスのコンストラクタ");
  }
}

サブクラスの Foods クラスのオブジェクトを作成すると、スーパークラスである Product クラスのコンストラクタが自動的に呼び出されているのが確認できます。

superキーワード(1)

このように super() を明示的に記述しなくてもスーパークラスのコンストラクタは呼び出されます。ただし、自動で呼び出されるのは引数がないスーパークラスのコンストラクタです。引数があるコンストラクタを呼び出したい場合は、 super(引数) のように明示的に記述する必要があります。

class Product {
	private String name;

  Product(String name) {
    this.name = name;
  }
}

class Foods extends Product {
  Foods() {
    super("未定義");
  }
}

この場合、 Foods クラスのオブジェクトを作成されると Foods クラスのコンストラクタが呼び出されますが、先頭の行でスーパークラスである Product クラスの引数ありのコンストラクタを呼び出しています。このように super() を使用することで、スーパークラスで定義されている複数のコンストラクタの中から任意のコンストラクタを呼び出すことができます。

注意点として super() を使用する場合は、コンストラクタの最初の行に記述する必要があります。

class Food extends Product {
  Foods() {
    super();
    System.out.println("Foodsクラスのコンストラクタ");
  }
}

別の処理を実行したあとで super() を呼び出すとコンパイルエラーとなります。

class Food extends Product {
  Foods() {
    System.out.println("Foodsクラスのコンストラクタ");
    super();
  }
}

※ super() を使用する場合は先頭行でなければならないという仕様は現在変更されており、先頭行以外でも super() を呼び出すことができるようになりました。

サンプルコード

では簡単なサンプルを作って試してみます。テキストエディタで次のように記述したあと、 Sample.java という名前で保存します。

public class Sample {
  public static void main(String[] args) {
    Foods f = new Foods("アメリカ", "オレンジ");

    System.out.println("名前は" + f.getName() + "です");
    System.out.println("原産地は" + f.getPlace() + "です");
  }
}

class Product {
  private String name;

  Product (String name) {
    this.name = name;
  }

  public String getName() {
    return name;
  }
}

class Foods extends Product {
  private String place; 

  Foods (String place, String name) {
    super(name);
    this.place = place;
  }

  public String getPlace() {
    return place;
  }
}

コンパイルを行います。

javac -encoding UTF-8 Sample.java

その後で、次のように実行してください。

java Sample

superキーワード(2)

Product をスーパークラスに持つ Foods クラスを定義しました。 Foods クラスのオブジェクトを作成したときに、コンストラクタの中でスーパークラスのコンストラクタを引数付きで呼び出しています。このようにサブクラスのコンストラクタの中からスーパークラスのコンストラクタを呼び出すことができます。

-- --

オブジェクト指向における super キーワードの使い方について解説しました。

( Written by Tatsuo Ikura )

プロフィール画像

著者 / TATSUO IKURA

これから IT 関連の知識を学ばれる方を対象に、色々な言語でのプログラミング方法や関連する技術、開発環境構築などに関する解説サイトを運営しています。