1. ホーム
  2. java

Javaにおけるメソッド隠蔽とは?JavaDocの説明でもわかりにくい

2023-11-15 09:16:39

疑問点

ジャバドック は言う。

の場合、呼び出される隠しメソッドのバージョンはスーパークラスのものであり、呼び出されるオーバーライドされたメソッドのバージョンはサブクラスのものである。

は私にはピンと来ません。この意味を示す明確な例があれば、非常にありがたいです。

どのように解決するのですか?

public class Animal {
    public static void foo() {
        System.out.println("Animal");
    }
}

public class Cat extends Animal {
    public static void foo() {  // hides Animal.foo()
        System.out.println("Cat");
    }
}

ここで Cat.foo() を隠すと言われています。 Animal.foo() . 静的メソッドはポリモーフィックではないので、隠蔽はオーバーライドのようにはいきません。そのため、以下のようなことが起こります。

Animal.foo(); // prints Animal
Cat.foo(); // prints Cat

Animal a = new Animal();
Animal b = new Cat();
Cat c = new Cat();
Animal d = null;

a.foo(); // should not be done. Prints Animal because the declared type of a is Animal
b.foo(); // should not be done. Prints Animal because the declared type of b is Animal
c.foo(); // should not be done. Prints Cat because the declared type of c is Cat
d.foo(); // should not be done. Prints Animal because the declared type of d is Animal

クラスではなくインスタンスに対して静的メソッドを呼び出すことは、非常に悪い習慣であり、決して行ってはいけません。

これをインスタンスメソッドと比較すると、インスタンスメソッドはポリモーフィックであり、したがってオーバーライドされます。呼び出されるメソッドは、オブジェクトの具体的な、実行時の型に依存します。

public class Animal {
    public void foo() {
        System.out.println("Animal");
    }
}

public class Cat extends Animal {
    public void foo() { // overrides Animal.foo()
        System.out.println("Cat");
    }
}

すると、以下のようになります。

Animal a = new Animal();
Animal b = new Cat();
Cat c = new Cat();
Animal d = null;

a.foo(); // prints Animal
b.foo(); // prints Cat
c.foo(); // prints Cat
d.foo(): // throws NullPointerException