public class A {
public A() {
foo();
}
private void foo() {
System.out.print("A::foo ");
goo();
}
public void goo() {
System.out.print("A::goo ");
}
}
public class B extends A {
public B() {
foo();
}
public void foo() {
System.out.print("B::foo ");
}
public void goo() {
System.out.print("B::goo ");
}
public static void main(String[] args) {
A b = new B() {
public void foo() {System.out.print("Anonymous::foo ");}
public void goo() {((B)this).foo();}
};
}
}
我希望您帮助理解为什么程序会打印A::foo Anonymous::foo Anonymous::foo
。这个匿名类是否取代了前B?覆盖它的方法?
正如我所看到的那样,它应该转到A的默认构造函数,运行A的foo-打印“A :: foo”,而不是运行B的goo,因为它已被正确覆盖,但现在B的goo是Anonymous类中的一个,所以它将它转换为B(什么都不做),然后运行它的foo,这是B的上面的foo,所以它应该打印“Anonymous:foo”。我有什么问题?
非常感谢。
答案 0 :(得分:4)
你的问题并不是那么清楚,但是我只想说答案是完全相同的,如果不是一个扩展B
的匿名类,你就有了一个顶级类{{1} } C
。匿名类没有任何内容使它们在多态性和继承方面表现不同。当B
的构造函数调用B
时,将调用派生程度最高的类中的重写版本(此处为匿名类)。
答案 1 :(得分:4)
我认为这里令人困惑的是你有两个foo方法。一个是私有的,所以它没有资格覆盖,另一个是公共的,所以它可以被覆盖。 B在其构造函数中调用foo,但是它被子类覆盖了。
答案 2 :(得分:3)
A的构造函数调用A.foo(A :: foo),因为它是私有的,因此不会重载。 A.foo调用goo(),它被B覆盖,然后被Anonymous覆盖,所以你得到Anonymous.goo - > Anonymous.foo(Anonymous :: foo)。然后B的构造函数调用foo,它被Anonymous所覆盖(Anonymous :: foo)
答案 3 :(得分:1)
使用这种匿名构造实际上创建了B的子类。您已经使用您在匿名类中提供的方法覆盖了B的方法,因此将使用这些方法。