匿名类,继承和覆盖

时间:2011-09-13 14:04:03

标签: java inheritance anonymous overrides

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”。我有什么问题?

非常感谢。

4 个答案:

答案 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的方法,因此将使用这些方法。