java编译器如何知道继承的方法?
我们在Java中使用继承来抽象出一个超类中的类似行为,并让所有子类继承它。这样做的优点之一是,我们现在只有一个方法的副本需要维护(即在超类中)java编译器如何知道继承的方法?,java,inheritance,compiler-construction,Java,Inheritance,Compiler Construction,我们在Java中使用继承来抽象出一个超类中的类似行为,并让所有子类继承它。这样做的优点之一是,我们现在只有一个方法的副本需要维护(即在超类中) 我试图理解Java编译器如何知道sleep()方法用于Cat类型引用。在Cat子类中不能有该方法的副本(它破坏了将其包含在超类中并让所有子类从中继承的目的)。此信息是否存储在其他位置?当编译器看到fluffy.sleep()时,它首先在Cat类中查找名为sleep的公共实例方法,该方法不带参数。由于找不到它,它在继承链上移到Animal,并对Animal
我试图理解Java编译器如何知道
sleep()
方法用于Cat
类型引用。在Cat
子类中不能有该方法的副本(它破坏了将其包含在超类中并让所有子类从中继承的目的)。此信息是否存储在其他位置?当编译器看到fluffy.sleep()
时,它首先在Cat
类中查找名为sleep
的公共实例方法,该方法不带参数。由于找不到它,它在继承链上移到Animal
,并对Animal
执行相同的检查。它在那里找到了,所以一切都很好
除了代码和Java字节码之外,这些信息实际上并不“存储”在任何地方。对于接口,我们可以在它们上调用对象类方法,而无需接口扩展对象。 例如:-
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规范9.2中:
如果一个接口没有直接的超级接口,那么该接口隐式声明一个公共抽象成员方法m,其签名为s,返回类型为r,并抛出与每个公共实例方法m对应的子句t,该方法的签名为s,返回类型为r,抛出子句t在Object中声明,除非是一个抽象方法
使用相同的签名、相同的返回类型和兼容的throws子句
由接口显式声明。
如果接口在对象中将m声明为final的情况下显式声明这样的方法m,则这是编译时错误。当接口编译代码时,它会创建某种类继承人/数据结构。对吗?@Twister是的。当对象在运行时创建时,它们(或至少运行时VM)存储它们的类型。我说的是编译时而不是运行时。@Twister是的,我只是用“是”回答了编译时的问题。我可以进一步说,当编译器查看代码时,它们确实会形成代码定义的类型树,因此当编译其余代码时,它知道所有类型都是什么。否则,它将不知道什么是未定义的引用,什么不是。
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.
}