【问题标题】:design pattern / multiple inheritance workaround java设计模式/多重继承解决方法java
【发布时间】:2013-08-16 22:29:06
【问题描述】:

我有一个带有类层次结构的 Java 包,比如带有子类 A1、A2、A3 的 A 类...

对于特定的应用程序,我需要创建实现接口 B 的类(类型 A)。这些新类将有一些共同点,所以我的第一个想法是创建一个从 A 继承并实现 B 的基类 C ,而我的新类 C1、C2、C3、... 将仅从 C 继承。但是,其中一些类 Ci 将需要 Aj 之一中存在的功能,并且通过这种方法,我需要重新实现此类功能(功能未在 A 中定义)。对于某些 Ci,我想从各种 Ai 继承行为,但同时继承 C 中所有 Ci 共有的其他行为。当然,Java 不允许多重继承,所以我不能这样做这个直接我当然不想仅仅因为不支持 MI 就重新实现这么多东西,但我看不到解决方法。有什么想法吗?

【问题讨论】:

  • 如果我们有一张图表可以更容易地看到发生了什么。
  • 似乎在 80% 的情况下,多重继承的解决方案是 Strategy Pattern。不过我还没有找到另外 20%。

标签: java design-patterns multiple-inheritance


【解决方案1】:

您真的需要子类化还是只想重用代码?

听起来您使用复合模式和可能的策略模式:

您的 C 类将具有 A 类型和可能 B 类型的字段,并在适当的情况下将调用委托给它们。这为您提供了代码重用的所有优势,而没有继承的混乱(单个或多个)

【讨论】:

  • 我希望子类和代码都可以重用,但是是的,我需要的这个应用程序的子类关系实际上只有 C 和子类 Ci(用于多态性),但我认为我不需要子类 A 是的,也许我可以在 C 中包含 A 类型的字段,并且各种 Ci 可以根据需要实例化 Aj 类型的对象。看起来不错,如果我没有预见到问题,我会再考虑一下并尝试一下。谢谢!
【解决方案2】:

当每个人第一次开始看到类层次结构的有用性时,他们似乎都注意到了这个问题。问题源于类中的正交问题。一些子类共享特征 1,一些共享特征 2。有些则两者都没有。有些人两者都有。

如果只有一个特征……(比如说,有些有内部,因此可以填充。)……我们会很好。创建一个中间子类来处理这些问题。一些子类实际上是中间子类的子类。我们已经完成了。

但是有两个并且没有办法进行子类化。我认为多重继承是该问题的一种解决方案,但它增加了一定程度的复杂性并颠覆了使分层类结构有用的思维简单性。

我发现最好将子类化用于它可以轻松解决的一个问题。然后选择一种方法来隔离和共享代码,而不是子类化。

一种解决方案是提取功能并将其移至其他位置。然后所有的 Aj 和 Ci 都可以在那里调用它。优点是不用复制粘贴任何代码,如果坏了可以在一个地方修复。

一个 代码可以进入基类 A 并指定一个名称,表明它仅适用于某些子类。使方法受到保护。然后从实际的类中调用它们。它丑陋但有效。

一个

protected String formStringForSubclassesAjAndCi(String a, int b) {
    return a + b;
}

Ci 和 Aj

public String formString(String a, int b) {
    return formStringForSubclassesAjAndCi(a, b);
}

两个类似地,您可以将共享代码放在某种帮助器类中:

CiAjHelper

public static String formStringForSubclassesAjAndCi(String a, int b) {
    return a + b;
}

Aj 和 Ci

public String formString(String a, int b) {
    return CaAjHelper.formStringForSubclassesAjAndCi(a, b);
}

第三种方法是把代码放在Aj 中,然后从Cj 调用它,方法是为每个Ci 实例创建一个Aj 实例并将公共函数委托给它。 (它仍然很丑。)

Aj

public String formString(String a, int b) {
    return a + b;
}

Cj

private Aj instanceAj = new Aj();

public String formString(String a, int b) {
    return instanceAj.formString(a, b);
}

【讨论】:

  • true,但在这种特殊情况下,我希望尽可能避免更改现有包,即 A 和 Ai 应该希望保持固定。也许这太麻烦了,我会回到这个。
  • 那么#3 可能会有所帮助。一旦我将其编辑为实际从 1 计数到 3。
猜你喜欢
  • 1970-01-01
  • 2023-04-08
  • 2019-12-05
  • 1970-01-01
  • 1970-01-01
  • 2017-02-11
  • 2019-07-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多