Java多态函数调用
无法理解两个函数调用的输出为何为“3”和“4”。因为Java多态函数调用,java,polymorphism,extends,Java,Polymorphism,Extends,无法理解两个函数调用的输出为何为“3”和“4”。因为 g2.foo( t1 ); 在编译时,g2是类型A,它查找在其主类中找不到的foo(类型C),因此它查看其子类B,然后是C。因此foo(…)应该绑定到 public void foo(C p) { System.out.println("5"); } 子类C正确吗 然后在运行时,g2将是类型C并调用foo(cp),这将导致输出为“5”。我不确定我对多态性的逻辑/理解哪里是错误的 class A { public void
g2.foo( t1 );
在编译时,g2是类型A,它查找在其主类中找不到的foo(类型C),因此它查看其子类B,然后是C。因此foo(…)应该绑定到
public void foo(C p) {
System.out.println("5");
}
子类C正确吗
然后在运行时,g2将是类型C并调用foo(cp),这将导致输出为“5”。我不确定我对多态性的逻辑/理解哪里是错误的
class A {
public void foo(A p) {
System.out.println("1");
}
}
class B extends A {
public void foo(B p) {
System.out.println("2");
}
}
class C extends B {
public void foo(A p) {
System.out.println("3");
}
public void foo(B p) {
System.out.println("4");
}
public void foo(C p) {
System.out.println("5");
}
}
public class HelloWorld {
public static void main(String[] args) {
A g2 = new C();
B r2 = new C();
C t1 = new C();
g2.foo(t1); // 3
r2.foo(new C()); // 4
}
}
要记住的主要一点是,重载方法是根据调用该方法的实例的编译时类型在编译时选择的。运行时类型仅确定所选方法是否被运行时类型的实现覆盖 g2.foo(t1)
g2
有一个编译类型a
,这意味着在编译时只能选择public void foo(ap)
。在运行时g2
在C
的实例中,这意味着调用C
的public void foo(ap)
,并打印3
r2.foo(新的C())
r2
具有编译类型B
,因此可以在编译时选择public void foo(ap)
或public void foo(bp)
public void foo(bp)
是最好的重载匹配(因为B
比A
更具体)。在运行时,r2
是C
的一个实例,因此调用C
的public void foo(bp)
,并打印4
在编译时,g2是类型A,它查找foo(类型C),在它的主类中找不到foo,因此它查找它的子类B,然后是C。所以foo(…)应该绑定到
你的这种理解是错误的
class A {
public void foo(A p) {
System.out.println("1");
}
}
class B extends A {
public void foo(B p) {
System.out.println("2");
}
}
class C extends B {
public void foo(A p) {
System.out.println("3");
}
public void foo(B p) {
System.out.println("4");
}
public void foo(C p) {
System.out.println("5");
}
}
public class HelloWorld {
public static void main(String[] args) {
A g2 = new C();
B r2 = new C();
C t1 = new C();
g2.foo(t1); // 3
r2.foo(new C()); // 4
}
}
在编译期间,由于类型A
中没有foo(C)
,它标志着将调用方法foo(A)
(因为A
是C
的超类型,并且它是最具体的匹配方法)
在运行时,调用特定方法(foo(A)
)的C
实现并打印3
。下一次调用也类似。当您调用g2.foo(t1)时
g2获取A的编译类型对象,这意味着ie的方法
public void foo(A p)
但在运行时,g2是C类的对象,因此每当重写函数时,就会调用public void foo(ap),派生类的虚拟表(v-table)将该函数与其实现映射。因此,函数调用将调用该特定类的v表所给出的实现 在您的例子中,g2=新的C();创建C的实例,因此v-table会将foo函数与其(C的)实现映射 现在,当函数调用发生时,即在g2.foo(t1)上,类C的实现将被调用,因为它已映射,因此3将被打印