java traits还是mixins模式?

时间:2008-11-04 19:36:05

标签: java mixins traits

有没有办法在java中模拟mixins或traits?基本上,我需要一种方法来进行多重继承,这样我就可以将常用的业务逻辑添加到几个类

8 个答案:

答案 0 :(得分:17)

不是你想要的方式。 Effective Java建议您“赞成合成而不是继承”。这意味着您将公共逻辑移动到其他类和委托。这就是你如何解决java中缺少多重继承的问题。

答案 1 :(得分:12)

我会将所有业务逻辑封装到一个新类BusinessLogic中,并让每个需要BusinessLogic的类调用该类。如果您需要为调用BusinessLogic的类创建一个单一的heirarchy,那么您还必须创建一个接口(BusinessLogicInterface?)

在伪代码中:

interface BusinessLogicInterace
{
    void method1();
    void method2();
}

class BusinessLogic implements BusinessLogicInterface
{
    void method1() { ... }
    void method2() { ... }
}

class User 
    extends OtherClass 
    implements BusinessLogicInterface
{
    BusinessLogic logic = new BusinessLogic();

    @Override
    void method1() { logic.method1(); }

    @Override
    void method2() { logic.method2(); }
}

这不是解决缺少多重继承的最漂亮的实现,当接口有很多方法时,它变得非常麻烦。最有可能的是,您需要尝试重新设计代码以避免需要mixins。

答案 2 :(得分:4)

今天对象纯粹主义者在搅拌吗?

认为你可以用一些面向复合的编程吗?

然后你,先生,正在寻找Apache Polygene(以前的Qi4J或Zest);)

答案 3 :(得分:3)

Java对多重继承的回答是能够实现多个接口。当然,这意味着你将获得方法声明,但不是逻辑。

您可以尝试通过组合模拟mixins:您的Java类可以定义表示执行某些常见业务逻辑的其他类的成员变量。

在设计Java类时,我没有发现缺少C ++样式的多重继承来阻止我的架构设计。你会找到一种方法来实现你想要做的事情。

答案 4 :(得分:3)

QI4J允许您使用mixins

答案 5 :(得分:2)

您可以利用接口允许嵌套类(自动公共静态)来保持接口本身封装的接口方法的默认实现这一事实。即在界面中移动Alex B的例子的BusinessLogic类。

这类似于Scala为特征生成JVM代码的方式,如此处所述How are Scala traits compiled into Java bytecode?

执行此操作时,示例变为:

interface BusinessLogicInterface {
    void method0();

    class DefaultImpl {
        private DefaultImpl() {
        }

        public static void method1(BusinessLogicInterface self) { ... }
        public static void method2(BusinessLogicInterface self) { ... }
    }

    void method1();
    void method2();
}

class User extends OtherClass implements BusinessLogicInterface {
    @Override
    void method0() { ... }

    @Override
    void method1() { BusinessLogic.defaultImpl.method1(this); }

    @Override
    void method2() { BusinessLogic.defaultImpl.method2(this); }
}

请注意,我们将接口类型的对象作为“self”参数传递。这意味着业务逻辑可以使用其他抽象方法(方法0)。这对于使用彼此正交的抽象方法创建特征以及可以根据这些正交方法实现的实用程序“扩展”方法非常有用。

缺点是每个接口必须复制/粘贴样板代理代码。 Java中另一个经常使用的模式没有这个缺点(但内聚力较少,调用方法的方式较少)是创建一个具有复数名称的类作为包含静态方法的接口,这在Collections实用程序类中使用。 / p>

答案 6 :(得分:0)

使用CGLib / javassit在java中实现简单的mixin / traits支持非常简单。 您可以查看实例here作为小例子。 可以找到更完整,随时可用的解决方案:here

答案 7 :(得分:0)

从Java-8开始,添加了默认的接口方法。这与Java中的多个接口继承一起应该允许某种混合。显然,接口必须独立运行。因此,会有很大的局限性。