在Java中实现Mixin?

使用Java 6,我该如何实现一个mixin? 在Ruby中,这是非常容易和可能的。 我怎样才能得到类似的Java?

你可以使用CGLIB 。 Mixin类可以从几个接口/对象委托生成一个dynamic类:

 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) 

我会说只是使用对象组合。 每当你想要投入新的function,作为一个成员编写另一个对象到类中。 如果要使所有混合类具有相同的types,则可以使用数组作为成员对象,其中每个元素都与其他元素组成,并且可以将其分派给特定的元素。

由于Java只支持单inheritance,所以这是不可能的。 看看WP:Mixin 。

编辑 :由于关于接口的意见:mixin很酷的事情是,你可以结合他们,而不写组合的代码。 有了接口,你必须自己实现组合的function(除了你可以扩展的一个类)!

最简单的方法是使用静态导入。 它允许重用代码,看起来像是类的一部分,但是在其他地方是真正定义的。

优点:

  • 真的很容易
  • 你可以“混入”尽可能多的静态import,只要你喜欢

缺点:

  • 静态方法将无法访问“this”,所以你必须手动传递它
  • 没有状态:你的静态方法不能有自己的实例字段。 它们只能定义自己的静态字段,然后由调用静态方法的任何对象共享。
  • 无法在客户端类中定义公共方法(将代码混入其中)。 在Ruby中,导入一个mixin实际上将这些公共方法定义为你的类的公共方法。 在Java中,在这种情况下,inheritance将是更好的解决scheme(假设您不需要扩展多个类)

例:

 import static my.package.MyHelperUtility.methodDefinedInAnotherClass; public class MyNormalCode { public void example() { methodDefinedInAnotherClass(); } } 

我知道Java 6的问题,但在Java 8中,我们将有一个相当不错的select: 默认方法 。

我们将能够添加接口方法的“默认”实现,所以我们可以添加新的方法而不会破坏实现接口的每个类。

只要你的mixin不需要状态,你可以在一个界面中编写代码。 然后,你的class级可以实现尽可能多的接口,因为它想要和繁荣, 你有mixin 。

这是对系统的滥用吗? 有一点,但它没有进入任何多重inheritance问题,因为没有状态。

当然,这也是这种方法最大的缺点。

从某种意义上说,一个Ruby混合input与Java抽象类是等价的,否则不能在Java中实现混合input。 你可以靠近使用接口,因此在你的混音中绝对没有代码,但是你不能直接达到与Ruby混合input相同的行为。

浏览http://code.google.com/p/javadude/wiki/AnnotationsMixinExample

它使用了我创build的一组注释。

注意:我正在对注释进行重大更新,其中包括一些API损坏。 我计划在接下来的几周内发布一个新版本。

刚跑过去: http : //www.berniecode.com/blog/2009/08/16/mixins-for-java/

更新:Qi4j现在是Apache Polygene, https ://polygene.apache.org

Qi4j对Mixins的定义可能是相当独特的,因为它不是以基类开始的。 通过这个极端,应用程序如何build立的全新范例就出现了,我们称之为“面向复合编程”(Composite Oriented Programming)。 复合是“对象”的等价物,不仅是Mixins连接在一起,还包括Constraints(validation),Concerns(围绕build议)和SideEffects(不能改变方法结果)。

所以我认为Qi4j有一个非常强大的Mixin故事。 Mixin可以是“types的”或“通用的”,它们可以是公开的(可以在组合之外访问)或纯粹私有的(在组合内)。 Qi4j强烈定义了什么属性,并继续有内置持久性,这不会将存储实现泄漏到您的域中(警告:Qi4j泄漏到您的域)。 而一旦持久实体进入图片,一个协会的强烈的定义也需要(包括在Qi4j)。

请参阅http://www.qi4j.org/state-modeling.html以获得良好的概述。;

在Qi4j中,只有Mixins有状态。 限制/担忧/ SideEffects不能有状态(如果他们需要参考一个私人混合)。

要在Qi4j中定义一个组合,可以在types本身上进行结构化,或者在运行时模型创build时的引导时进行。

结构上;

 @Mixins({PetrolEngfineMixin.class,FourWheelsMixin.class})
公共接口Car扩展了HasEngine,HasWheels,EntityComposite
 {}

在开机时,

公共接口车
 {} 

公共类CarModuleAssembler
实现汇编
{
公共无效汇编(ModuleAssembly模块)
{
module.entities(Car.class)
.withMixins(PetronEngineMixin.class,FourWheelsMixin.class);
}
}

然而,这恰恰触及了Qi4j的特征表面。

在Java中混入mixins: http : //jonaquino.blogspot.com/2005/07/java-mixin-pattern-or-faking-multiple.html

您现在可以使用AspectJ ITD (如5,6,7)对Java 进行混合 。 Java 8当然会增加更好的防御方法。

我相信这可能会回答你的问题…虽然我不完全确定我明白什么是混合尚未…

是的,在Java中实现mixin approach的最简单和方便的方法是使用包含静态方法的某个类的静态导入。

不确定你正在寻找什么mixin的function,但其中的大部分可以使用装饰模式来完成。

http://en.wikipedia.org/wiki/Decorator_pattern#Java

我正在探索为Java 7提供这个function。我的第一步是使用本文中显示的示例:

  • Mixins在纯Java

它应该与java 6一起工作,它类似于上面的其他注入选项。 基于我在C#和Ruby中的Mixins的经验,你应该实现混合,而不是模仿或伪造它。

另一个模型,是与jackson一起使用的模型:

  • Jackson MixIn注释

如果您可以使用新的Java 8版本,请说明是否处于预发行模式,这可能会有所帮助。

  • Java 8:你现在有mixin?

使用虚拟扩展方法,这需要努力成为一个混合。 所以在我看来,这还算是早期,我更喜欢第一个链接提供的更清洁的方法(或类似的方法)。

在面向方面的编程运动中,术语“Mixin”不等同于Java术语“aspect”吗? AspectJ可能值得一看。

一个老问题的答案。

我看了一下Apache Zest。 也许这只是我,但我觉得这些例子有点麻烦。 我不明白这一点。 另一个select可能是对象组。

但我build议你可以看看这个回购:

https://github.com/Mashashi/javaroles/

它可能会部分涵盖你想要做的事情。 看起来很简单。

这里是一个例子:

定义angular色的接口:

 public interface Human { String hello(); String die(String age); String eat(); String dance(); } public interface Monkey {String hello(); String eat();} 

定义刚性typesAnimalRoles …

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

定义class级angular色Bonobo …

 public class Bonobo implements Monkey{ public Bonobo() {} @Override public String hello(){ return "Ugauga"; } @Override public String eat() { return "Nhamnham"; } } 

定义课堂angular色葡萄牙语…

 @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!"; } } 

运行testing…

 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!" 

请看看我的小示范项目如何使用cglib在纯java中创buildmixins。 主要它只是一个代理生成器的调用。 这是盟友 该示例包含一个junittesting用例,演示如何即时代理。

https://github.com/literadix/JavaMixins