【问题标题】:Confusion about superclass references and subclass objects关于超类引用和子类对象的混淆
【发布时间】:2012-05-08 05:12:18
【问题描述】:

我对此代码有一些疑问:

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. 为什么子类需要一个范围更广的访问修饰符?

【问题讨论】:

标签: java inheritance reference modifier overriding


【解决方案1】:
  1. refvar 被声明为 superclass 对象,这就是为什么必须在 superclass 中声明 bark() 才能编译 refvar.bark()

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

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

【讨论】:

    【解决方案2】:

    为什么在这种情况下父级必须要有方法, 孩子有没有?

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

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

    是的,事实上这就是我上面所说的。

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

    实际上,编译器下一步不会去任何地方。编译时重要的是bark() 是对superclass 类型对象的有效调用。只有在运行时调用才会被分派到subclass 中声明的bark() 覆盖。

    为什么子类需要一个范围更广的访问修饰符?

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

    例如,如果您被允许将subclass 中的bark() 更改为private,那么理论上对该方法的调用不应在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
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-30
      • 1970-01-01
      • 2017-04-30
      • 1970-01-01
      • 1970-01-01
      • 2011-12-02
      • 2010-11-22
      相关资源
      最近更新 更多