java java特征或mixins模式?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/263121/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 11:41:03  来源:igfitidea点击:

java traits or mixins pattern?

javamixinstraits

提问by joshjdevl

Is there a way to emulate mixins or traits in java? basically, I need a way to do multiple inheritance so I can add common business logic to several classes

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

采纳答案by Alex B

I would encapsulate all of the business logic into a new class BusinessLogicand have each class that needs BusinessLogicmake calls to the class. If you need a single rooted heirarchy for your classes that make calls to BusinessLogic, you'll have to create an interface as well (BusinessLogicInterface?)

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

In pseudo-code:

在伪代码中:

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(); }
}

This isn't the prettiest implementation to work around a lack of multiple inheritance and it becomes quite cumbersome when the interface has a lot of methods. Most likely, you'll want to try and redesign your code to avoid needing mixins.

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

回答by sblundy

Not the way you want to do it. Effective Javarecommends that you "Favor composition over inheritance". Meaning you move the common logic to other classes and delegate. This is how you get around the lack of multiple inheritance in java.

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

回答by Chris Vest

Is the object-purist stirring in you today?

今天你是否有一种纯粹的客体?

Think you could do with a little composite oriented programming?

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

Then you, sir, are looking for Apache Polygene(formerly Qi4J or Zest) ;)

那么,先生,您正在寻找ApachePolygene(以前的 Qi4J 或 Zest);)

回答by Pablo La Greca

QI4J allows you to use mixins

QI4J 允许你使用 mixins

回答by David Koelle

Java's answer to multiple inheritance is the ability to implement multiple interfaces. Of course, this means you'll get the method declarations, but not the logic.

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

You could try emulating mixins by composition: your Java class could define member variables that represent other classes that perform some common business logic.

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

In designing Java classes, I have not found the lack of C++ style multiple inheritance to inhibit the design of my architecture. You will find a way to achieve what you want to do.

在设计 Java 类时,我没有发现缺乏 C++ 风格的多重继承来抑制我的架构设计。你会找到一种方法来实现你想做的事情。

回答by Henno Vermeulen

You can exploit the fact that interfaces allow nested classes (automatically public static) to keep the default implementation of the interface methods encapsulated within the interface itself. I.e. move the BusinessLogic class of Alex B's example inside the interface.

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

This is similar to the way Scala generates the JVM code for traits as explained here How are Scala traits compiled into Java bytecode?

这类似于 Scala 为特征生成 JVM 代码的方式,如此处解释的 Scala 特征如何编译成 Java 字节码?

When doing this the example becomes:

这样做时,示例变为:

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); }
}

Note that we pass an object of the interface type as the "self" parameter. This means the business logic can use other abstract methods (method0). This can be very useful for creating a trait with abstract methods that are all orthogonal to each other and utility "extension" methods that may be implemented in terms of these orthogonal methods.

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

The drawback is that each interface must copy/paste the boilerplate delegation code. Another often used pattern in Java without this drawback (but with less cohesion and less OO way to call the methods) is to create a class with the plural name as the interface containing the static methods, this is used in the Collections utility class.

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

回答by user3478180

As of Java-8, default interface methods were added. This, together with multiple inheritance of interfaces in Java should allow some sort of mixin. Clearly the interfaces have to operate independently. So, there will be significant limitations.

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

回答by x_rex

Implementing simple mixin/traits support in java using CGLib/javassit is quite easy. You can take a look for instance herefor small example. More complete, ready to use solution might be found: here

使用 CGLib/javassit 在 java 中实现简单的 mixin/traits 支持非常容易。您可以在此处查看示例以获取小示例。可能会找到更完整、随时可用的解决方案:here