English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Java 基礎教程

Java 流程控制

Java 数组

Java 面向对象(I)

Java 面向对象(II)

Java 面向对象(III)

Java 異常処理

Java 列表(List)

Java Queue(队列)

Java Map集合

Java Set集合

Java 输入输出(I/O)

Java Reader/Writer

Javaの他のトピック

Java メソッドのオーバーライド

このチュートリアルでは、Javaでのメソッドのオーバーライドを例を用いて学びます。

前のチュートリアルでは、継承について学びました。継承はOOPの属性であり、既存のクラス(親クラス)から新しいクラス(子クラス)を派生させることができます。子クラスは超クラスの属性とメソッドを継承します。

今、親クラスと子クラスの両方で同じメソッドが定義されている場合、子クラスのメソッドが親クラスのメソッドをオーバーライドします。これはメソッドのオーバーライド(メソッドの再定義)と呼ばれます。

例1:メソッドのオーバーライド

class Animal {
   public void displayInfo() {
      System.out.println("私は動物です。");
   }
}
class Dog extends Animal {
   @Override
   public void displayInfo() {
      System.out.println("私は犬です。");
   }
}
class Main {
   public static void main(String[] args) {
      Dog d1 = new Dog();
      d1.displayInfo();
   }
}

出力

I am a dog.

上記のプログラムでは、displayInfo()メソッドがAnimalの親クラスとDogの子クラスの両方に存在しています。

私たちがdを使用する際に、1オブジェクト(子クラスのオブジェクト)がdisplayInfo()を呼び出したとき、子クラスDogのメソッドが呼び出されます。子クラスのdisplayInfo()メソッドは、親クラスの同じメソッドをオーバーライドしています。

この例では@Overrideアノテーションを使用しています。Javaでは、コメントはコンパイラに情報を提供するメタデータです。ここでは、@Overrideアノテーションはコンパイラに、アノテーション後のメソッドがオーバーライドされるメソッドを示しています。

@Overrideを使用することは強制ではありません。しかし、このメソッドを使用する場合、该方法はオーバーライドのすべてのルールに従う必要があります。そうしないと、コンパイラはエラーを生成します。

Javaのオーバーライドルール

  • 親クラスと子クラスは同じメソッド名、同じ返却型、同じ引数リストを持たなければなりません。

  • finalおよびstaticと宣言されたメソッドはオーバーライドできません。

  • 私たちは常に抽象メソッド(後のチュートリアルで説明します)を超クラスでオーバーライドするべきです。

Javaのオーバーライドでのsuperキーワード

Javaでオーバーライドを実行する際によくある問題は:

 オーバーライド後に超クラスのメソッドにアクセスできますか?

答えは肯定的

例2:superキーワードの使用

class Animal {
   public void displayInfo() {
      System.out.println("私は動物です。");
   }
}
class Dog extends Animal {
   public void displayInfo() {
      super.displayInfo();
      System.out.println("私は犬です。");
   }
}
class Main {
   public static void main(String[] args) {
      Dog d1 = new Dog();
      d1.displayInfo();
   }
}

出力

私は動物です。
I am a dog.

上記の例では、子クラスDogが超クラスAnimalのdisplayInfo()メソッドをオーバーライドしています。

私たちはDog子クラスのd1displayInfo()メソッドを呼び出すオブジェクトは、Dog子クラス内のメソッドを呼び出します。親クラス内のメソッドは呼び出されません。

Dog子クラスのdisplayInfo()内部で、super.displayInfo()を使用して親クラスのdisplayInfo()を呼び出します。

Javaではコンストラクタは継承されません。したがって、Javaではコンストラクタのオーバーライドのような問題は存在しません。

しかし、その子クラスから超クラスのコンストラクタを呼び出すことができます。そのために、super()を使用します。詳細については、Javaのsuperキーワード

オーバーライド中のアクセス修飾子

親クラスおよびその子クラスで宣言された同じメソッドは異なるアクセス修飾子を持つことができますが、ある制限があります。

私たちは、親クラスのアクセス修飾子よりもアクセス権を広げる子クラスで使用できるアクセス修飾子だけを使用できます。例えば、

仮に親クラスのメソッドmyClass()がprotectedと宣言されていると仮定すると、myClass()の同じメソッドは子クラスではpublicまたはprotectedであってはならない。

例3:オーバーライド中のアクセス修飾子

class Animal {
   protected void displayInfo() {
      System.out.println("私は動物です。");
   }
}
class Dog extends Animal {
   public void displayInfo() {
      System.out.println("私は犬です。");
   }
}
class Main {
   public static void main(String[] args) {
      Dog d1 = new Dog();
      d1.displayInfo();
   }
}

出力

I am a dog.

上記の例では、子クラスDogが親クラスAnimalのdisplayInfo()メソッドをオーバーライドしています。

私たちはdを使用して、1(子クラスのオブジェクト)displayInfo()を呼び出すと、子クラス内のメソッドが呼び出されます。

注意,displayInfo()はAnimalの親クラスでprotectedとして宣言されています。该方法はDogの子クラスでpublicアクセス指定子(public)を持っています。これは、publicがprotectedよりも大きなアクセス権限を提供するためです。

抽象メソッドのオーバーライド

Javaでは、抽象クラスは他のクラスの親クラス(基底クラス)として作成されます。また、クラスに抽象メソッドが含まれている場合、それをオーバーライドする必要があります。

後のチュートリアルでは、抽象クラスと抽象メソッドのオーバーライドに関する情報を学びます。