【问题标题】:How to do this without multiple inheritance如何在没有多重继承的情况下做到这一点
【发布时间】:2012-01-02 18:09:16
【问题描述】:

我有一组扩展单个抽象类的类。这些类的一个子集需要其中一个方法的相同实现,类的另一个子集需要该方法的另一个实现,而第三个子集需要另一个。总共有大约十个子类,但其中一种方法只有三种可能的实现。 (类实现的许多其他方法没有共同点。)

我正在尝试找出实现这一目标的最佳方法。我认为我在 C++ 中会做的是多重继承:创建三个只实现此方法的类,然后让子类从这三个类中的适当一个继承。

是否有在 Java 中执行此操作的最佳实践?

我正在考虑在主要抽象类和子抽象类之间设置三个抽象类的中间层。这三个中的每一个都从主抽象类继承,并实现了所讨论的方法。然后孩子们从这三个人那里继承。但是我不喜欢的是,如果另一种方法带有类似的“分组”行为,并且它不对应于三个“中间层”类怎么办?那会变得丑陋

这有任何意义吗?我写的很匆忙……

编辑:因此,在提出我的问题 24 小时后,我收到了大约六种要调查的模式。我还不确定它们都是官方的设计模式名称。但我将调查每一个,然后报告(并选择正确的答案)。目前建议的模式:

* Delegation

* Bridge

* Strategy

* Composition

* Decorator (if I was choosing on name alone, I choose this one)

我还需要补充一点,正在实现的方法需要访问该类的几乎所有私有成员。所以这将是我选择的重要因素。

【问题讨论】:

    标签: java inheritance


    【解决方案1】:

    实际上,我在这里闻到了一种策略模式。

    您可以在基类中将该方法委托给在构造时传递的策略。子类只是传递一组策略中的任何一个作为其构造的一部分。策略本身可以在课堂之外提供,也可以在内部作为私人课程提供。这最终可能会导致层次结构中的总体类减少。

    话虽如此,即使使用我提出的解决方案,这里也有其他气味。您可能希望在更高级别上考虑接口(如其他解决方案所述)和仅没有继承的组合。随着时间的推移,我得出结论,继承不是我的朋友。现在我尽可能避免它。

    【讨论】:

    • 策略不必只适用于一种方法。我可以有一个实现多种方法的策略(如果它们完全以这种方式分组)。我也可以有多个 Strategy 接口和实现,然后在构建时根据需要将它们组合起来。只是一个想法。不一定是最佳答案。编辑:这是对我输入时 被删除的评论的回应。 :)
    • 我非常喜欢你的回答,我删除了我的。如果还需要在类之间共享另一个方法,也可以再次使用策略模式。
    • 对不起,我删除了评论...这是错误的,我的回答也是如此。但正如你从我上面的新评论中看到的那样,我完全同意你的看法。
    • 啊,想知道那里发生了什么。感谢您的澄清(和支持!)Toto2。
    • 对于策略模式,我做了类似 MyX x = new MyXChild(new MyStrategy()); MyStrategy 在哪里实现有问题的方法?另一个问题:我是否正确地认为使用“组合”功能是由成员变量类实现的,因此无法访问我的子类的私有和受保护成员?
    【解决方案2】:

    使用委托而不是继承。让同一个组的所有类委托给一个公共帮助对象来实现它们的方法。

    【讨论】:

    • 我认为桥接和策略模式也归结为委托。您认为哪种模式最好?还是我们应该不使用这里的模式(因为辅助类本身并不是一个模式)?我认为提问者现在有多个答案,所有这些答案本身都没有错……
    • 策略模式似乎是最合适的一种,除了策略模式在于将策略注入到类中。在这种情况下,我认为这些类不必从外部进行配置。方法必须只是从类中外部化。一切都不能有模式名称,在这里简单的委托就足够了。
    • 同意。模式很好,但不应该在不完全合适的地方使用。
    • 谢谢 JB。我想我明白你的建议。但我想确定。 “委托”是指子类中的方法对辅助对象的方法进行显式调用?另外,“委托”是“官方”设计模式名称吗? (谁维护官方设计模式名称的注册表?)
    • 哦等一下!我忘了提到我需要访问几乎所有实例的私有成员(十几个事物函数和变量)。那么,在这样的模式中,有这样的要求,孩子是否将它的“this”引用传递给委托方法?
    【解决方案3】:

    如果您坚持通过继承来解决它,GoF 书中的 bridge pattern 可能会有所帮助(它可能会也可能不会完美契合,具体取决于导致分离为三个实现的领域问题)。就我个人而言,我很可能只是将这三个方法实现放入一个辅助类中并转发来自这些类的方法调用(JB Nizet 正确地将其称为委托)。

    【讨论】:

    • 感谢您提供的链接,我将阅读并带回我的问题。你还会听吗?我是新来的。发布到答案的 cmets 是否会向回答者发送某种警报?
    • 对答案的评论会触发一个小通知,但如果您有后续问题,更符合网站精神,将它们作为新问题发布(同时检查重复项),而不是在较早的一个。像这样的元讨论有its own sub-site,在这里不受欢迎。
    【解决方案4】:

    不使用继承的简单快速解决方案是将3个“常用方法”抽象到其他地方,然后重复方法调用。

    如果您想以一种不错的 OO 方式进行操作,请查看装饰器模式,这可能对您有帮助 - 创建 3 个标准类来实现您选择的三个方法,然后用其他类“装饰”它们.

    【讨论】:

      【解决方案5】:

      首先,考虑用接口替换抽象类。我不知道这是否可能 在你的情况下。

      其次,您可以将“分组”方法的功能委托给另一个类(实现者)。创建 3 个具有方法实现的不同类(或仅在某个类中创建 3 个不同方法),并根据需要从子类中调用它们。

      因此,“分组”方法将在每个子类中定义,但它只会显式调用 3 个可能的实现器之一。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-12-04
        • 2020-10-21
        • 1970-01-01
        • 1970-01-01
        • 2023-03-15
        • 1970-01-01
        • 2023-03-14
        • 2019-01-18
        相关资源
        最近更新 更多