在Java中作弊单一继承?

时间:2020-03-05 18:55:26  来源:igfitidea点击:

我听说有一种方法可以欺骗单一继承并在Java中实现多重继承。有谁知道如何实现这一点(不使用接口)?

出于好奇;-)

解决方案

回答

JAVA不支持多重继承。

我们可以获取它以实现多个接口,有些人将其视为解决问题的一种方法。就我个人而言,我还没有使用多重继承,所以我无法真正理解它的吸引力。

通常,当有人建议在cor JAVA中进行多重继承时,是由于在c ++中"他们可以"。我是"只是因为我们不能代表我们应该这样做"的粉丝。由于c&JAVA不支持它,为什么要强迫它去做它原本不打算做的事情。这并不是说在某些特殊情况下可以有效地实现垄断,只是通常可以将代码重构为不需要代码。

回答

解决这一问题的方法是使用合成而不是继承。实际上,这对可测试性也有很大帮助,因此通常是好的做法。

如果我们只想让类型像其他几种类型一样"表现",则可以从任意数量的接口中继承;我们显然不能从这些"借用"实现细节。

回答

使用interfaces。我们可以实现任意多个。通常,我们可以在复合模式(GoF)上使用某些变体,以便在需要时可以重用实现代码。

回答

我相信Java不支持多重继承的根本原因与C#相同;所有对象最终都是从Object派生的,并且它具有指向同一基类的多个路径对于编译器来说是模棱两可的。模糊==错误,因此编译器不允许这样做。

相反,我们可以通过委派来模拟多重继承。有关示例,请参见本文。

回答

我们可以使用java.lang.reflect.Proxy实例对其进行一些欺骗(我对此有一点强调)。

这实际上仅允许我们添加额外的接口,并在运行时将其调用委托给另一个实例。

作为指导和辅导新开发人员的人,如果有人向我展示执行此操作的代码,我将感到震惊。反射是我们真正需要了解的工具之一,在跳入之前对Java有很好的了解。我个人只做过一次,这是为了编写一些我无法控制实现某些接口的代码。我无法控制的其他代码(这是一个快速的hack,因此我不必编写和维护太多的粘合代码)。

回答

我们需要谨慎地将接口继承(本质上是指提供特定工具的合同继承)与实现继承(实现机制的继承)区分开。

Java通过实现机制提供了接口继承,我们可以拥有多个接口继承。

实现继承是扩展机制,我们只有一个版本。我们真的需要多重实现继承吗?我敢打赌,除非我们是Eiffel程序员,否则后果不堪设想。

回答

我们可以通过显式管理父类集并使用反射在所有父类中搜索目标方法来"模拟"它。我不想在生产中这样做,但这可能是一个有趣的玩具程序。通过利用反射,动态创建类并以编程方式调用编译器,我们可能会做很多奇怪的事情。

回答

我对此进行了更多思考,并意识到虽然动态代理可以工作(这是RMI(使用?)的工作方式),但是如果我们真的想要这种功能,那么最好使用类似于AspectJ(eclipse.org/aspectj)。

这样,我们可以将多个不同的方面放入一个类中,从而为我们提供伪mixin继承,而没有可怕的脆弱继承层次结构。

正如其他所有人所指出的那样,想要/需要多重继承通常表明我们没有从正确的角度解决问题。首先请记住GoF的"优先考虑组成而不是继承"原则!

回答

有人努力将mixins引入Java。检查此链接:http://www.disi.unige.it/person/LagorioG/jam/

回答

当然可以,但是这很棘手,我们应该真正考虑是否要这样做。
这个想法是结合使用基于范围的继承和基于类型的继承。出于内部目的,内部类"继承"外部类的方法和字段,这就是类型对话。这有点像mixin,其中将外部类混入到内部类中,但并不安全,因为我们可以更改外部类的状态以及使用其方法。
Gilad Bracha(主要的Java语言设计师之一)写了一篇讨论该问题的论文。
因此,假设我们想在一些不相关的类之间共享一些内部使用的方法(例如,用于字符串操作),则可以将它们的子类创建为具有所有所需方法的类的内部类,并且这些子类可以使用父类和外部类中的方法。

无论如何,对于复杂的类来说这很棘手,我们可以使用静态导入(从Java 5开始)获得大多数功能。不过,对于工作面试和酒吧测验来说,这是一个很大的问题;-)

回答

Java不支持SingleMultiple继承,相反,它具有实现相同目的的接口。如果我们坚持使用多重继承,则应在C ++中完成。

回答

通过使用内部类,这也是C ++有时更喜欢的:内部类惯用语。