English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
このチュートリアルでは、Javaのsuperキーワードを例を通じて学びます。
Javaのsuperキーワードは、子クラスで親クラスのメンバ(属性、コンストラクタ、メソッド)にアクセスするために使用されます。
superキーワードについて学ぶ前に、以下を確認してください。Java インheritance。
子クラスでオーバーライドされた親クラスのメソッドを呼び出します。
親クラス(superclass)と子クラス(subclass)が同じ名前の属性を持っている場合、親クラスの属性(フィールド)にアクセスします。
子クラスのコンストラクタから明示的に親クラスの無引数コンストラクタまたは引数付きコンストラクタを呼び出します。
これらすべての用途について説明しましょう。
親クラスと子クラスで同じ名前のメソッドが定義されている場合、子クラスのメソッドが親クラスのメソッドをオーバーライドします。これはメソッドのオーバーライド。
class Animal { //メソッド public void display(){ System.out.println("I am an animal"); } } class Dog extends Animal { //メソッドのオーバーライド @Override public void display(){ System.out.println("I am a dog"); } public void printMessage(){ display(); } } class Main { public static void main(String[] args) { Dog dog1 = new Dog(); dog1.printMessage(); } }
出力結果
I am a dog
この例では、Dogクラスのオブジェクトdogを生成します1、そのメソッドprintMessage()を呼び出すことができます。そのメソッドはdisplay()ステートメントを実行します。
display()が2つのクラスで定義されているため、子クラスDogのメソッドが親クラスAnimalのメソッドをオーバーライドしています。したがって、子クラスのdisplay()が呼び出されます。
親クラスのオーバーライドメソッドを呼び出す方法はどうですか?
親クラスAnimalのオーバーライドメソッドdisplay()を呼び出す必要がある場合、super.display()を使用します。
class Animal { //メソッド public void display(){ System.out.println("I am an animal"); } } class Dog extends Animal { //メソッドのオーバーライド @Override public void display(){ System.out.println("I am a dog"); } public void printMessage(){ //これはオーバーライドされたメソッドを呼び出します display(); // これは親クラスのメソッドを呼び出します super.display(); } } class Main { public static void main(String[] args) { Dog dog1 = new Dog(); dog1.printMessage(); } }
出力結果
I am a dog I am an animal
ここでは、上記のプログラムがどのように動作するかを説明します。
親クラスと子クラスは同じ名前の属性を持つことができます。superキーワードを使用して親クラスの属性にアクセスします。
class Animal { protected String type="動物"; } class Dog extends Animal { public String type="哺乳動物"; public void printType() { System.out.println("私は " + type); System.out.println("私は一匹犬です " + super.type); } } class Main { public static void main(String[] args) { Dog dog1 = new Dog(); dog1.printType(); } }
出力:
私は哺乳動物 私は動物
この例では、スーパークラスAnimalと派生クラスDogに同じインスタンスフィールドのタイプを定義しました。
それでは、Dogクラスのオブジェクトdogを生成しました1。このオブジェクトを使用してprintType()メソッドを呼び出します。
printType()関数内部で、
type - は派生クラスDogの属性を指します。
super.type - はスーパークラスAnimalの属性を指します。
したがって、System.out.println("我是 " + type);出力「私は哺乳動物"そして、System.out.println("我是一只 " + super.type);プリント出力「私は動物"。
誰もが知っているように、クラスのオブジェクトを作成すると、自動的にデフォルトコンストラクタが呼び出されます。
派生クラスのコンストラクタからスーパークラスのコンストラクタを明示的に呼び出すには、super()を使用します。これはsuperキーワードの特別な形式です。
注意:super()は子クラスのコンストラクタ内でのみ使用でき、最初の文でなければなりません。
class Animal { //Animalクラスのデフォルトまたは無パラメータのコンストラクタ Animal() { System.out.println("I am an animal"); } } class Dog extends Animal { // Dogクラスのデフォルトまたは無パラメータのコンストラクタ Dog() { //スーパークラスのデフォルトコンストラクタを呼び出す super(); System.out.println("I am a dog"); } } class Main { public static void main(String[] args) { Dog dog1 = new Dog(); } }
出力結果
I am an animal I am a dog
ここで、Dogクラスのオブジェクトdog1が作成されると、自動的にそのクラスのデフォルトまたは無パラメータのコンストラクタが呼び出されます。
派生クラスのコンストラクタの中で、super()文がスーパークラスのコンストラクタを呼び出し、その中の文を実行します。したがって、私たちが得る結果"I am an animal"。
その後、プログラムの流れは派生クラスのコンストラクタに戻り、残りの文を実行します。したがって、"I am a dog"がプリントアウトされます。
しかし、super()を使用する必要はありません。派生クラスのコンストラクタにsuper()を使用していない場合でも、コンパイラは暗黙的にスーパークラスのデフォルトコンストラクタを呼び出します。
必要がある場合、コンパイラが自動的にsuper()を呼び出すので、なぜ明示的にそれを使用し、冗長コードを使用する必要がありますか?
派生クラスのコンストラクタからスーパークラスのパラメータ付きコンストラクタ(パラメータ付きのコンストラクタ)を使用する必要があります。
パラメータ付きsuper()常に派生クラスのコンストラクタ体の最初の文でないと、コンパイルエラーが発生します。
class Animal { //デフォルトまたは無パラメータのコンストラクタ Animal() { System.out.println("I am an animal"); } //パラメータ付きコンストラクタ Animal(String type) { System.out.println("Type: ")}+type); } } class Dog extends Animal { //デフォルトのコンストラクタ Dog() { //呼び出す超クラスのパラメータ化されたコンストラクタ super("Animal"); System.out.println("I am a dog"); } } class Main { public static void main(String[] args) { Dog dog1 = new Dog(); } }
出力結果
Type: Animal I am a dog
コンパイラは無パラメータのコンストラクタを自動的に呼び出すことができますが、パラメータ付きのコンストラクタを呼び出すことはできません。
パラメータ化されたコンストラクタを呼び出す必要がある場合、子クラスのコンストラクタ内で明示的に定義する必要があります。上記のコードの例のように:
super("Animal");
上記の例では、super("Animal")を使用して、パラメータ化されたコンストラクタを明示的に呼び出しました。この場合、コンパイラは超クラスのデフォルトのコンストラクタを呼び出しません。