【问题标题】:Multiple inheritance quagmire - which class is instantiated?多重继承泥潭——实例化了哪个类?
【发布时间】:2019-01-28 06:12:15
【问题描述】:

假设我有以下课程:

abstract class A {
    static abstract class _Foo {}
}

class B extends A {
    static void doSomething() {
        System.out.println(C.saySomething());
    }

    static _Foo getInner() {
        return new C._Foo();
    }

    static abstract class _Foo extends A._Foo {}
}

final class C extends D {
    static String saySomething() {
        return "Something";
    }
}

abstract class D {
    static class _Foo extends B._Foo {
        public int value() {
            return 42;
        }
    }
}

提供一些上下文:

  • 所有这些类都位于同一个包中。
  • CD在编译时生成
  • AC 类永远不会被实例化;他们只是为B 类提供一些行为
  • B 类是唯一实际使用的类。
  • D 直到编译后才知道,这就是为什么我们只在B 中使用C

这与使用 google autovalue 时可能期望的相似


我的问题是关于B 中的getInner 函数:

  1. 哪个_Foo 将在return new C._Foo(); 行被实例化?是D 中的_Foo 还是A 中的那个?
  2. 这种未定义的行为是实例化还是记录在案? 如果可能,请提供文件
  3. 顺序是如何确定的?

最后一个问题仅供参考,我最感兴趣的是前两个。

感谢您的帮助。

【问题讨论】:

  • 你试过了吗?你发现了什么?
  • @JimGarrison 有机会我会去的,但我主要是想看看是否有人有一些描述这种行为的文档的链接。即使我发现实例化了哪一个,我仍然需要知道我是否依赖于未定义的行为
  • 我不确定您如何想象在该行上获得 A._Foo - 您已明确地将表达式限定为 new C._Foo() - 所以它必须是通过 C 公开的 _Foo ,它必须是来自 D... 的那个(尽管我承认我希望编译器抱怨 C 中没有明确的 _Foo...)
  • @moilejter,这是有道理的。我不知道我昨天在想什么

标签: java multiple-inheritance undefined-behavior auto-value


【解决方案1】:

回答你的三个问题……

  1. D 中的_Foo 实例将从new C._Foo() 返回。
  2. 不,不是; _Foos 是声明它们的类的“成员”,因此它们像变量一样被继承。 (在这种情况下,就像静态变量一样。) [规范] (https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.2)。 (这是我能收集到的最好的文档。)
  3. 顺序由类C 立即继承的内容决定。由于C 扩展了DC 将继承D 的所有内容(即D._Foo)。如果D 没有声明一个名为_Foo 的类,那么D 将继承B_Foo,然后C 将继承它。

希望这会有所帮助。 :)

【讨论】:

    猜你喜欢
    • 2023-03-11
    • 2017-11-25
    • 2020-06-14
    • 1970-01-01
    • 2019-08-11
    • 2012-02-06
    • 2015-07-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多