任何人都可以告诉我什么时候初始构造函数初始化和调用已经完成。它是在编译时还是在运行时发生的。即使我相信它发生在运行时,但当有人问及,编译器如何在没有构造函数初始化的情况下检查父子关系,我感到困惑。例如
我们有一个父类College
和子类Department
编辑
class College
{
public String getCollegeName()
{
return "ABC College";
}
}
class Department extends College
{
public static void main(String args[])
{
College s = new Department();
System.out.println(s.getCollegeName());
System.out.println(s.getDepartName());
}
public String getDepartName()
{
return "IT Department";
}
}
这里没有调用Department s = new College()
编译器怎么知道s有一个派生的getDepartName()
方法。
答案 0 :(得分:1)
你的例子在某种程度上是一个特例。在一个非平凡的程序中,您通常无法确定某个引用所指向的对象的类别,而不是“它是声明引用的类型或其子类型”。
多态的整个概念基于这样一个事实:具体类只在运行时知道,而不是在编译时知道。这当然意味着编译器必须确保在引用上调用的方法在运行时在引用的对象上可用。唯一适用的方法是声明变量的类的方法(包括超类中所有继承的方法)。
答案 1 :(得分:1)
它发生在运行时。 “编译器怎么知道s有一个派生的getCollegeName()方法。” - 因为编译器知道s是College和College的实例,有getCollegeName()方法。你告诉过s是学院的一个实例
College s
如果你这样做
Object s = new College();
那么你只能调用Object所拥有的方法,因为编译器无法知道s是College
答案 2 :(得分:1)
s
使用类型Department
声明,并且编译器已经知道Department
继承自College
,因此所有方法都在Department
中声明<{1}}(因为College
派生自Department
)可以被调用。
这样做有效,因为您不允许将任何内容(College
除外)分配给null
,而不是s
或从中派生的类。
不需要执行构造函数,因为所有内容都可以根据声明的Department
类型来确定。