-2

このコードについていくつか質問があります。

class superclass
{
    void bark() {}
}

class subclass extends superclass
{
    void bark() {}

    public static void main(String[] args) {
        superclass refvar = new subclass();
        refvar.bark();
    }
}
  1. この場合、子がメソッドを持っているかどうかに関係なく、親がメソッドを持っている必要があるのはなぜですか? コンパイル時に参照変数はスーパークラス型であると言われたので、コンパイラはコンパイル時にスーパークラスでこのメソッドをチェックします。それは正確ですか?

  2. コンパイラが を読み取るとき、bark()次の行先をどのように知るのでしょうか? 子メソッドがそれをオーバーライドすることは知っていますが、最初にスーパークラスのメソッドまたはサブクラスに行くことと、その理由を知りたいです。

  3. サブクラスがより広い範囲のアクセス修飾子を持つ必要があるのはなぜですか?

4

2 に答える 2

1
  1. refvarsuperclassオブジェクトとして宣言されているため、コンパイルするbark()にはで宣言する必要があります。superclassrefvar.bark()

  2. インスタンスオブジェクトのの実装を探しますbark()

  3. より狭い範囲に何かをオーバーライドすることはあまり意味がありません。

于 2012-05-08T05:35:36.810 に答える
1

この場合、子がメソッドを持っているかどうかに関係なく、親がメソッドを持っている必要があるのはなぜですか?

あなたの例はbark()、静的に型付けされたオブジェクトを呼び出していますsuperclass-superclassメソッドを宣言しなかった場合bark()、コンパイラはこれが有効な呼び出しであることを知りません。

コンパイル時に参照変数はスーパークラスタイプであると言われているので、コンパイラはコンパイル時にスーパークラスでこのメソッドをチェックします。それは正確ですか?

はい、実際、これは私が上で言ったことに沿っています。

コンパイラがを読み取るとき、bark()次にどこに行くべきかをどのように知るのでしょうか?子メソッドがそれをオーバーライドすることは知っていますが、最初にスーパークラスメソッドまたはサブクラスに送られることとその理由を知りたいです。

実際、コンパイラは次にどこにも行きません。コンパイル時に重要bark()なのは、型のオブジェクトに対する有効な呼び出しであるということだけですsuperclassbark()で宣言されたオーバーライドに呼び出しがディスパッチされるのは、実行時のみsubclassです。

サブクラスに、より広いスコープのアクセス修飾子が必要なのはなぜですか?

ここでは、サブクラスのオーバーライドされたメソッドを意味していると思います。明確にするために、それは同等以上のアクセス権を持っている必要があります。アクセスを狭めることができない理由は、スーパークラスによって定義されたコントラクトが破られるためです。

たとえば、に変更bark()することprivateが許可されている場合subclass、そのメソッドの呼び出しは理論的にはの外では機能しないはずですsubclass。しかし、プライベートにsuperclassしないので、それは機能する必要があります:bark()

class ClassInTheSamePackageAsTheOtherTwo {

    public static void main(String[] args) {
        superclass refvar = new subclass();
        refvar.bark(); //as far as the compiler knows, this call is valid
    }
}
于 2012-05-08T05:36:00.447 に答える