java 特性还是 mixins 模式?

发布于 2024-07-08 12:58:54 字数 73 浏览 8 评论 0原文

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

小情绪 2024-07-15 12:58:54

不是你想要的方式。 Effective Java 建议您“优先选择组合而不是继承”。 这意味着您将通用逻辑移至其他类和委托。 这就是解决 java 中缺乏多重继承的问题的方法。

Not the way you want to do it. Effective Java recommends 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.

你丑哭了我 2024-07-15 12:58:54

我会将所有业务逻辑封装到一个新类 BusinessLogic 中,并让每个需要 BusinessLogic 的类调用该类。 如果您的类需要调用 BusinessLogic 的单根层次结构,则还必须创建一个接口(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(); }
}

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

I would encapsulate all of the business logic into a new class BusinessLogic and have each class that needs BusinessLogic make 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?)

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.

ゃ懵逼小萝莉 2024-07-15 12:58:54

今天,物体纯粹主义者在你心中激荡吗?

您认为您可以进行一些面向复合的编程吗?

那么您,先生,正在寻找Apache Polygene(以前名为 Qi4J,后来更名为 Zest 和/或 Apache-Zest);)

更新 2022; 目前已停产,但无论如何还是有用的。

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 named Qi4J, then it renamed to Zest and/or Apache-Zest) ;)

Update 2022; It's discontinued currently, but useful anyway.

倥絔 2024-07-15 12:58:54

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

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

当这样做时,示例变成:

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”参数传递。 这意味着业务逻辑可以使用其他抽象方法(method0)。 这对于使用彼此正交的抽象方法和可以根据这些正交方法实现的实用程序“扩展”方法创建特征非常有用。

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

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.

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

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.

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.

沧桑㈠ 2024-07-15 12:58:54

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

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

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

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.

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

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.

世界和平 2024-07-15 12:58:54

QI4J 允许您使用 mixin

QI4J allows you to use mixins

命硬 2024-07-15 12:58:54

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

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.

安穩 2024-07-15 12:58:54

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

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文