使用Java 6,如何实现mixin?在Ruby中它非常简单易行。我怎样才能在Java中获得类似的东西?
答案 0 :(得分:21)
您可以使用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)
答案 1 :(得分:13)
我会说只使用对象组合。每次想要引入新功能时,将另一个对象作为成员组成类。如果要创建所有相同类型的混合类,可以使用数组作为成员对象,其中每个元素都由其他所有元素组成,并且可以调度到特定元素。
答案 2 :(得分:13)
我知道Java 6的问题,但在Java 8中,我们将有一个相当不错的选择:default methods。
我们将能够添加接口方法的“默认”实现,因此我们可以添加新方法,而不会破坏实现接口的每个类。
只要你的mixin不需要状态,你就可以在界面中编写代码。然后,您的班级可以根据需要实现尽可能多的接口,并you've got mixins。
这是滥用系统吗?一点点,但它没有涉及任何多重继承问题,因为没有状态。
当然,这也是这种方法的最大缺点。
答案 3 :(得分:8)
由于Java仅支持单继承,因此这是不可能的。看看WP: Mixin。
编辑:由于有关接口的评论:关于mixins的一个很酷的事情是你可以在不编写组合代码的情况下组合它们。使用接口,您必须自己实现组合的功能(除了可以扩展的一个类)!
答案 4 :(得分:7)
最简单的方法是使用静态导入。它允许代码重用“看起来”像它是类的一部分,但实际上是在其他地方定义的。
优点:
缺点:
示例:
import static my.package.MyHelperUtility.methodDefinedInAnotherClass;
public class MyNormalCode {
public void example() {
methodDefinedInAnotherClass();
}
}
答案 5 :(得分:5)
从某种意义上说,Ruby混合相当于Java抽象类,不,你不能在Java中实现混合。你可以通过使用接口来完成,因此在你的混合中绝对没有定义任何代码,但是你不能直接实现与Ruby混合中相同的行为。
答案 6 :(得分:5)
Qi4j对Mixins的定义可能非常独特,因为它不是以基类开头的。通过走向这个极端,出现了一个关于如何构建应用程序的全新范例,我们将其称为面向复合的编程。 Composite是'对象'等价物,不仅是Mixins连接在一起,还有Constraints(验证),Concerns(围绕建议)和SideEffects(不能改变方法结果)。
所以我认为Qi4j有一个非常强大的Mixin故事。 Mixins可以是“打字”或“通用”,它们可以是公共的(可以在复合材料之外访问)或纯粹私有(在Composite中)。 Qi4j强烈定义属性是什么,并继续具有内置持久性,这不会将存储实现泄漏到您的域中(警告; Qi4j泄漏到您的域)。一旦持久化实体进入图片,就需要对关联进行强有力的定义(并包含在Qi4j中)。
有关概述,请参阅http://www.qi4j.org/state-modeling.html。
在Qi4j中,只有Mixins有状态。约束/关注/ SideEffects不能有状态(如果他们需要参考私人混音)。
要在Qi4j中定义合成,可以在类型本身上进行结构化处理,也可以在创建运行时模型时的引导时进行。
结构上;
@Mixins({PetrolEngfineMixin.class, FourWheelsMixin.class})
public interface Car extends HasEngine, HasWheels, EntityComposite
{}
开机时;
public interface Car
{}
public class CarModuleAssembler
implements Assembler
{
public void assemble( ModuleAssembly module )
{
module.entities( Car.class )
.withMixins( PetronEngineMixin.class, FourWheelsMixin.class );
}
}
然而,这只是触及Qi4j中的特征表面。
答案 7 :(得分:4)
查看http://code.google.com/p/javadude/wiki/AnnotationsMixinExample
它使用了我创建的一组注释。
注意:我正在对注释进行重大更新,其中包括一些API破坏。我打算在接下来的几周内发布一个新版本。
答案 8 :(得分:4)
答案 9 :(得分:2)
答案 10 :(得分:2)
不确定您正在寻找的mixins的哪些功能,但很多功能都可以使用装饰器模式完成。
答案 11 :(得分:2)
你现在可以用Java做Mixins(即5,6,7)using AspectJ ITDs。 Java 8当然会通过其防御方法添加更好的功能。
答案 12 :(得分:1)
是的,在Java中实现mixins方法的最简单方便的方法是使用包含静态方法的某些类的静态导入。
答案 13 :(得分:1)
我正在探索为Java 7提供这个。我的第一个剪辑是使用本文中显示的示例:
它应该与java 6一起使用,它类似于上面的其他注入选项。基于我在C#和Ruby中使用Mixins的经验,你应该专注于实现mixins,而不仅仅是模仿或伪造它。
另一个模型是与Jackson一起使用的模型:
如果您可以使用新的Java 8版本,请说明您是否处于预发布模式,这可能有所帮助。
使用虚拟扩展方法,这需要努力 是'混入。所以在我看来它还处于早期阶段,我更喜欢第一个链接提供的更清晰的方法(或类似方法)。
答案 14 :(得分:1)
我相信this可能会回答你的问题......虽然我还不完全sure I understand what a mixin is yet...
答案 15 :(得分:0)
术语'Mixin'在面向方面的编程运动中不等同于Java术语'方面'吗? AspectJ可能值得一看。
答案 16 :(得分:0)
对旧问题的回答。
我看了一下Apache Zest。也许只是我,但我发现这些例子有点麻烦。我无法理解这一点。另一种选择可能是对象团队。
但我建议你看一下这个回购:
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!"
答案 17 :(得分:0)
请看一下我的小型演示项目如何使用cglib在纯java中创建mixins。主要是它只是一个代理生成器的调用。这是盟友。该示例包含一个junit测试用例,演示如何即时代理代理。