-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. refvar被声明为superclass对象,这就是为什么bark()必须在superclassfor中声明refvar.bark()才能编译。

  2. 它查找实例对象的bark().

  3. 在更窄的范围内覆盖某些东西没有多大意义。

于 2012-05-08T05:35:36.810 回答
1

为什么在这种情况下,无论孩子有没有方法,父母都必须有方法?

您的示例调用bark()静态类型的对象superclass- 如果superclass没有声明方法bark(),编译器将不知道这将是一个有效的调用。

我被告知在编译时引用变量是超类类型,所以编译器在编译时检查超类中的这个方法;那准确吗?

是的,事实上这与我上面所说的一致。

当编译器读取bark()时,它如何知道下一步要去哪里?我知道子方法会覆盖它,但我想知道它首先进入超类方法或子类,以及为什么。

实际上,编译器下一步不会去任何地方。在编译时重要的是bark()对类型对象的有效调用superclass。仅在运行时将调用分派bark()subclass.

为什么子类需要具有更广泛范围的访问修饰符?

我假设您的意思是子类的覆盖方法。澄清一下,它必须具有平等或更广泛的访问权限。它不能具有更窄访问权限的原因是因为这会破坏超类定义的合同。

例如,如果您被允许更改bark()privatein 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 回答