我们在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
子类中不能有该方法的副本(它违背了在超类中使用它并让所有子类继承它的目的)。这些信息是否存储在其他地方?
答案 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,那么这是一个编译时错误。