java编译器如何知道继承的方法?

时间:2015-07-13 17:03:53

标签: java inheritance compiler-construction

我们在Java中使用继承来抽象出超类中的类似行为,并让所有子类继承它。这样做的一个优点是,我们现在只有一个方法可以维护(即在超类中)。

Class Animal
{
   public void makeNoise()
   {

   }

   public void sleep()
   {

   }   
} 

Class Cat extends Animal
{
     // Override the makeNoise method
     public void makeNoise()
     {

     }
}

Class someClass
{
     public static void main(String args[])
     {
          Cat fluffy = new Cat();

          fluffy.sleep();
     }
}

我试图了解Java编译器如何知道sleep()类型引用的Cat方法。在Cat子类中不能有该方法的副本(它违背了在超类中使用它并让所有子类继承它的目的)。这些信息是否存储在其他地方?

2 个答案:

答案 0 :(得分:9)

当编译器看到fluffy.sleep()时,它首先在Cat类中查找名为sleep的公共实例方法,该方法不带参数。由于它没有找到它,它会将继承链向上移动到Animal,并对Animal执行相同的检查。它找到了它,所以一切都很好。

除了代码之外,这些信息并没有真正“存储”在任何地方,然后是Java字节代码。

答案 1 :(得分:0)

在接口的情况下,我们可以在没有接口扩展Object的情况下调用它们上的Object类方法。 例如: -

public interface Test { 
}

public class MyClass extends Object implements Test {

public static void main() {
Test test = new MyClass();
test.hashCode();
// You can call Object Class methods on Test interface and Test interface
//does not extends Object.

}

//在Java Specification 9.2中: - 如果接口没有直接的超接口,则接口隐式声明一个公共抽象成员方法m,其中包含签名s,返回类型r和throws子句t,对应于具有签名s的每个公共实例方法m,返回类型r和throws子句t在Object中声明,除非是抽象方法 具有相同的签名,相同的返回类型和兼容的throws子句 由接口显式声明。 如果接口在将对象声明为m的情况下显式声明了这样的方法m,那么这是一个编译时错误。