【问题标题】:Overcoming Java inheritance limitations (Opinions / Suggestions)克服 Java 继承限制(意见/建议)
【发布时间】:2017-02-26 23:34:38
【问题描述】:

所以我正在为 OpenGL/GLE 设计一个框架。

我创建了一个“纹理”抽象类。我有 Texture2D 和 TextureCubemap 继承自 Texture。从 Texture2D 我有 RenderTexture,从 TextureCubemap 我有 RenderTextureCubemap。现在这一切都很好,但是 RenderTexture 和 RenderTextureCubemap 有很多相似之处。我想消除他们之间目前的冗余。在其他语言中,这将是多重继承的理想场所,但 Java 不支持这一点。我的第二个想法是接口。这里的问题是我无法为接口方法定义主体,所以它并没有真正让我受益。另一种选择是创建一个“RenderTarget”类并将其添加为成员变量,虽然这可行,但我不喜欢每次我想访问“RenderTarget”中保存的内容时都必须跳过一个成员变量",看起来有点笨重。

我想知道是否有人可以提出更优雅的解决方案。

编辑:这是根据要求的图表。

【问题讨论】:

  • 你能添加某种形式的类图的截图吗?描述很好,但图片会更好。
  • 从 Java 8 开始,接口可以有default 方法,这些方法可以有主体。
  • @JornVernee 我怀疑这不是 default 的正确用例。
  • 默认方法仍然具有抽象的核心,并且是 OP 解决方案的一部分,但不是全部。首先,考虑组合而不是继承。很有可能这会解决大部分的问题。其次,Java 确实支持类型的多重继承。这实际上已经足够了。第三,混合组件而不是继承它们自然会导致使用依赖注入 (DI) 以及由此产生的所有美丽魔法。
  • @LewBloch 您指的是我在问题末尾所说的“另一种选择是创建一个“RenderTarget”类并将其添加为成员变量......”?还是我误会了?

标签: java inheritance multiple-inheritance


【解决方案1】:

实际上从 Java 8 开始,您可以在接口中定义方法体,请参阅https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html,因此这可能是一个解决方案。

正如 cmets 中所建议的,一个好的解决方案是将冗余代码放在不同的类中,并将其组合到您的两个渲染器中(即,创建一个拥有此代码的成员变量)。

如果这适用于这里,另一种可能性是将冗余因素考虑到辅助类(不可实例化且仅具有静态方法)并从您的 2 个渲染器轮询其静态方法。

【讨论】:

  • 这是真的,并且会很好用,但是我正在为 Android 构建,遗憾的是接口中的默认方法仅受 API 24 支持,我的目标是使此代码向后兼容,因此它规则此选项出去。但我同意,任何寻找通用 Java 答案的人都应该走这条路。
  • 不知道你的代码是什么样子肯定没有帮助,但如果你绝对想避免添加“RendererTarget”变量,我会尝试在帮助类中考虑冗余(使用静态方法,您不必携带完整的物品)。现在在 Java 中一直倾向于避免多重继承,例如这种缺失确保您不必为菱形问题而烦恼。
  • 小心。默认方法旨在表达编排,而不是实现。不要错误地将它们视为抽象类中的具体方法。
  • @LewBloch 不确定我是否关注。 Asettouf 将所有代码拆分成适合一页的易于理解的内容需要很长时间。否则我会添加它。
  • 我的意思是把具体的实现放到接口的默认方法中是很诱人的,但是太多的细节不利于接口的目的,定义类型。编排其他接口方法是一回事,这不需要了解实现类如何做他们的事情的内部知识。这是对默认方法的一个很好的使用。引入依赖关系、依赖特定的内部结构和其他此类细节是另一回事。谨慎行事,以便接口仍然只为实现者设置一个模式。
猜你喜欢
  • 2014-08-06
  • 1970-01-01
  • 2019-01-12
  • 1970-01-01
  • 2018-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-17
相关资源
最近更新 更多