在 Java 中实现 Mixin? [关闭]
Posted
技术标签:
【中文标题】在 Java 中实现 Mixin? [关闭]【英文标题】:Implement Mixin In Java? [closed] 【发布时间】:2010-10-09 21:40:44 【问题描述】:使用 Java 6,我如何实现 mixin?这在 Ruby 中非常简单且可行。我怎样才能在 Java 中得到类似的东西?
【问题讨论】:
你是说mixin?通常用多重继承完成的那种? mixin 也可以看成是一个实现了方法的接口。根据定义,这将是一个 Java 抽象类。 在 Java 8 中请参考@Brad Cupit 的答案:***.com/a/13992641/5290519。 【参考方案1】:由于 Java 只支持单继承,这是不可能的。看看WP: Mixin。
编辑:由于关于接口的 cmets:mixin 的酷之处在于您可以将它们组合起来而无需编写组合代码。使用接口你必须自己实现组合的功能(除了一个你可以扩展的类)!
【讨论】:
据说可以使用接口? 使用接口有一半可能。 Java支持动态类构建,所以是可以的。【参考方案2】:在 Java 中伪造 mixins:http://jonaquino.blogspot.com/2005/07/java-mixin-pattern-or-faking-multiple.html
【讨论】:
【参考方案3】:从某种意义上说,Ruby mix-in 等同于 Java 抽象类,不,您不能在 Java 中实现 mix-in。您可以通过使用接口来接近,因此在您的混入中绝对不定义任何代码,但您不能直接实现与在 Ruby 混入中相同的行为。
【讨论】:
【参考方案4】:看看http://code.google.com/p/javadude/wiki/AnnotationsMixinExample
它使用了我创建的一组注释。
注意:我正在对注释进行重大更新,其中包括一些 API 损坏。我计划在接下来的几周内发布一个新版本。
【讨论】:
【参考方案5】:我想说只使用对象组合。每次你想加入新功能时,将另一个对象作为成员组合到类中。如果你想让你的所有混合类都具有相同的类型,你可以使用一个数组作为成员对象,其中每个元素都由所有其他元素组成,你可以分派给一个特定的元素。
【讨论】:
【参考方案6】:您可以为此使用CGLIB。 Mixin 类能够从多个接口/对象委托生成动态类:
static Mixin create(java.lang.Class[] interfaces,
java.lang.Object[] delegates)
static Mixin create(java.lang.Object[] delegates)
static Mixin createBean(java.lang.Object[] beans)
【讨论】:
【参考方案7】:最简单的方法是使用静态导入。它允许代码重用“看起来”像是类的一部分,但实际上是在其他地方定义的。
优点:
真的很简单 您可以“混合”任意数量的静态导入缺点:
静态方法将无权访问 到“这个”,所以你必须通过它 手动输入 无状态:您的静态方法不能有自己的实例字段。它们只能定义自己的静态字段,然后由调用静态方法的任何对象共享。 无法在客户端类(其中混入了代码的类)上定义公共方法。在 Ruby 中,导入 mixin 实际上会将这些公共方法定义为类上的公共方法。在 Java 中,在这种情况下继承会是更好的解决方案(假设您不需要扩展多个类)例子:
import static my.package.MyHelperUtility.methodDefinedInAnotherClass;
public class MyNormalCode
public void example()
methodDefinedInAnotherClass();
【讨论】:
请不要这样做。你的对象会很快变得精神分裂,见en.wikipedia.org/wiki/…。此外,使用静态方法组合对象会使它们难以测试。 这只是一个实现细节;静态方法不会作为您的类上的方法公开。 “这个”没有混淆,所以我认为精神分裂症不适用,尽管读起来很有趣。 我没有说清楚,抱歉。静态代码很难测试。精神分裂症问题不是关于静态代码,而是更多关于在不知道“this”的方法中丢失上下文。如果您的“混合”方法之一需要访问“this”,您的方法是受对象精神分裂症的影响。 我会说如果 mixin 必须有状态,那就有问题了。您将拥有mixinMethod(this,mixinState)
而不是mixinMethod(this)
,这有点精神分裂。【参考方案8】:
刚刚遇到:https://blog.berniesumption.com/software/mixins-for-java/(Borken 链接已更新)
【讨论】:
-1;整个 SE 不鼓励仅链接的答案。请提供链接信息的摘要。链接总是有可能删除其内容的关键部分,或者在最坏的情况下变成 404。【参考方案9】:是的,在 Java 中实现 mixins 方法最简单、最方便的方法是从包含静态方法的某个类中使用静态导入。
【讨论】:
【参考方案10】:在面向方面的编程运动中,术语“混合”是否不等同于 Java 术语“方面”? AspectJ 可能值得一看。
【讨论】:
对不起,我没有看到你的答案,但你可以使用 AspectJ:***.com/questions/7403321/…【参考方案11】:更新:Qi4j 现在是 Apache Polygene,https://polygene.apache.org
Qi4j 对 Mixins 的定义可能非常独特,因为它不是从基类开始的。通过走向这个极端,一个全新的应用程序构建范式出现了,我们称之为面向复合编程。 Composite 是“对象”等价物,不仅将 Mixins 连接在一起,而且还有 Constraints(验证)、Concerns(围绕建议)和 SideEffects(不能改变方法结果)。
所以我认为 Qi4j 有一个非常强大的 Mixin 故事要讲。 Mixin 可以是“类型化的”或“通用的”,它们可以是公共的(可在组合外访问)或纯私有的(在组合内)。 Qi4j 强烈定义了属性是什么,并继续具有内置的持久性,它不会将存储实现泄漏到您的域中(警告;Qi4j 泄漏到您的域)。并且一旦持久化实体进入图片,还需要对关联的强定义(并包含在 Qi4j 中)。
请参阅http://www.qi4j.org/state-modeling.html 以获得良好的概述。
在 Qi4j 中,只有 Mixins 有状态。 Constraints/Concerns/SideEffects 不能有状态(如果有的话,它们需要引用私有 mixin)。
要在 Qi4j 中定义组合,可以在类型本身的结构上进行,或者在创建运行时模型时在引导时进行。
结构上;
@Mixins(PetrolEngfineMixin.class, FourWheelsMixin.class)
public interface Car extends HasEngine, HasWheels, EntityComposite
在启动时;
public interface Car
公共类 CarModuleAssembler 实现汇编器 公共无效组装(ModuleAssembly 模块) 模块实体(汽车类) .withMixins(PetronEngineMixin.class, FourWheelsMixin.class);
然而,这只是涉及 Qi4j 中功能的表面。
【讨论】:
【参考方案12】:默认方法
我知道问题是 Java 6,但在 Java 8 中我们会有一个相当不错的替代方案:default methods。
我们将能够添加接口方法的“默认”实现,因此我们可以添加新方法而不会破坏实现该接口的每个类。
只要你的 mixin 不需要状态,你就可以在接口中编写代码。然后,您的类可以实现任意数量的这些接口并繁荣,you've got mixins。
这是对系统的滥用吗?一点点,但它不会涉及任何多重继承问题,因为没有状态。
当然,这也是这种方法最大的缺点。
【讨论】:
【参考方案13】:您现在可以使用 Java(即 5、6、7)using AspectJ ITDs 进行 Mixins。 Java 8 当然会通过其防御方法添加更好的功能。
【讨论】:
防御者方法确实向前迈出了一大步。【参考方案14】:不确定您正在寻找 mixin 的哪些功能,但其中大部分可以使用装饰器模式完成。
http://en.wikipedia.org/wiki/Decorator_pattern#Java
【讨论】:
【参考方案15】:我正在探索为 Java 7 提供此功能。我的第一个选择是使用本文中显示的示例:
Mixins in Pure java它应该适用于 java 6,它类似于上面的其他注入选项。根据我在 C# 和 Ruby 中使用 Mixins 的经验,您应该致力于实现 mixins,而不仅仅是模拟或伪造它。
另一种模型,与Jackson一起使用的模型:
Jackson MixIn Annotations如果您可以使用新的 Java 8 版本,比如您处于预发布模式,那可能会有所帮助。
Java 8: You now have mixins?使用虚拟扩展方法,这需要努力'be-a' mixin。所以在我看来,这还为时尚早,我更喜欢第一个链接提供的更简洁的方法(或类似方法)。
【讨论】:
【参考方案16】:一个老问题的答案。
我查看了 Apache Zest。也许只有我一个人,但我发现这些例子有点麻烦。我不能完全理解这一点。另一种选择可能是对象团队。
但我建议你可以看看这个 repo:
https://github.com/Mashashi/javaroles/
它可能部分涵盖了您想要做的事情。看起来很简单。
这是一个例子:
为角色定义接口:
public interface Human
String hello();
String die(String age);
String eat();
String dance();
public interface Monkey String hello(); String eat();
定义刚性类型 AnimalRoles...
public class AnimalRoles implements Human, Monkey
public static final String HALLO = "Default hallo";
public static final String DIE = "Default they kill me...";
public static final String EAT = "Default eat...";
@ObjectForRole public Human human;
@ObjectForRole public Monkey monkey;
public AnimalRoles(Human human, Monkey monkey)
this.human = human;
this.monkey = monkey;
if(this.human!=null)
((Portuguese)this.human).core = this;
@Override
public String hello()
return HALLO;
@Override
public String die(String age)
return DIE+age;
@Override
@TurnOffRole
public String eat()
return EAT;
@Override
public String dance()
return "Just dance";
public String notInRole()
return "Oh oh";
定义类角色 Bonobo...
public class Bonobo implements Monkey
public Bonobo()
@Override
public String hello()
return "Ugauga";
@Override
public String eat()
return "Nhamnham";
定义类角色葡萄牙语...
@RoleObject(types = AnimalRoles.class )
public class Portuguese implements Human
public static final String HALLO = "Hey there";
public static final String DIE = "They killed me";
public static final String EAT = "Eating boiled pork now";
public AnimalRoles core;
public Portuguese()
@Override
public String hello()
return HALLO;
@Override
public String die(String age)
return DIE+age;
@Override
public String eat()
return EAT;
@Override
public String dance()
return core.dance()+" modified!";
运行测试...
new RoleRegisterComposition().registerRools();
AnimalRoles a = new AnimalRoles(new Portuguese(), new Bonobo());
System.out.println(a.hello());
System.out.println(a.dance());
将打印...
"Hey there"
"Dance modified!"
【讨论】:
上面提到的Qi4j在进入Apache时被命名为Apache Zest。后来改名为 Apache Polygene,以避免与 Eclipse Zest 项目的名称冲突。【参考方案17】:请看一下我的小演示项目如何使用 cglib 在纯 java 中创建 mixins。主要它只是对代理生成器的调用。这是盟友。该示例包含一个 junit 测试用例,演示如何实例化代理。
https://github.com/literadix/JavaMixins
【讨论】:
以上是关于在 Java 中实现 Mixin? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Java Spring 在 MySql 中实现多租户 [关闭]