【问题标题】:Anonymous class, Inheritance, and overriding匿名类、继承和覆盖
【发布时间】:2011-09-13 14:04:02
【问题描述】:
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-print "A::foo",而不是运行 B 的 goo,因为它已被正确覆盖,但现在 B 的 goo 是 Anonymous 类中的那个,所以它把这个转换为 B(什么都不做),并运行它的 foo,也就是 B 的上面的 foo,所以它应该打印“Anonymous:foo”。我怎么了?

非常感谢。

【问题讨论】:

    标签: java inheritance anonymous overriding


    【解决方案1】:

    您的问题不是很清楚,但我只想说,如果不是扩展B 的匿名类,而是扩展@987654323 的顶级类C,答案将完全相同@。匿名类并没有使它们在多态性和继承方面表现不同。当B 的构造函数调用foo() 时,将调用最派生类(此处为匿名类)中的覆盖版本。

    【讨论】:

    • 嗨 Ernest。你说写这个匿名类就像写一个从 B 扩展的类?它将是 b 的动态类型?
    • 赞成,因为提问者专门询问了匿名内部类,这解决了这个问题。
    【解决方案2】:

    我认为这里令人困惑的是你有两个 foo 方法。一个是私有的,所以它没有资格被覆盖,另一个是公共的,所以它可以被覆盖。 B 在其构造函数中调用 foo 但它被其子类覆盖。

    【讨论】:

    • 我不明白为什么它会打印正在打印的内容,我写了我认为应该做的事情,希望您的更正和解释。我在这种语法中误解了这个匿名类。
    • @Nir:EFH 的观点是否有帮助,重构为匿名子类命名会产生相同的结果?我猜匿名内部类语法会混淆这个问题。
    【解决方案3】:

    A 的构造函数调用 A.foo (A::foo) 因为它是私有的,所以没有重载。 A.foo 调用 goo() 被 B 覆盖,然后被 Anonymous 覆盖,所以你得到 Anonymous.goo -> Anonymous.foo (Anonymous::foo)。然后 B 的构造函数调用被 Anonymous 覆盖的 foo (Anonymous::foo)

    【讨论】:

      【解决方案4】:

      使用这种匿名构造实际上会创建 B 的子类。您已经用匿名类中提供的方法覆盖了 B 的方法,因此将使用这些方法。

      【讨论】:

      • 乔纳森韦瑟黑德,根据我自己的经验和痛苦,你是对的,这正是正在发生的事情。但是我在“官方”文档的任何地方都找不到这种行为的解释。你能帮忙找到吗?你从哪里得到这条信息的?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-20
      • 2019-06-29
      • 2012-09-15
      • 2017-09-21
      • 1970-01-01
      相关资源
      最近更新 更多