2012-05-08 43 views
-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

这是基本的面向对象编程的原则。请仔细阅读以下链接:http://docs.oracle.com/javase/tutorial/java/IandI/override.html – Seshagiri

回答

1
  1. refvar被声明为superclass对象,这就是为什么bark()具有superclassrefvar.bark()编译中声明。

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

  3. 重写某些东西到狭窄范围并没有多大意义。

1

为什么要为父母有一种方法在这种情况下,孩子 是否有不喜欢?

你的例子是调用静态类型为superclass的对象上bark() - 如果superclass没有申报的方法bark(),编译器会不知道这将是一个有效的呼叫。

据我所知,在编译时 参考变量是超类类型的,所以编译器检查 此方法中在编译时超类;那是准确的吗?

是的,实际上这是沿着我上面说的。

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

实际上,编译器不会去任何地方。编译时所有重要的是bark()是对superclass类型的对象的有效调用。只有在运行时,该呼叫才会发送到subclass中声明的bark()覆盖。

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

我假设你的意思是子类的覆盖的方法在这里。要澄清,它必须有等于或更广泛的访问权限。它不能有较窄访问的原因是因为这会破坏超类定义的合约。

例如,如果你被允许改变bark()是在subclassprivate,然后调用该方法在理论上不应该的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 
    } 
}