在Java中实现Mixin?
使用Java6,我如何实现一个?这在Ruby中是非常容易和可能的。我怎样才能在Java中得到类似的东西呢?因为Java只支持单一继承,这是不可能的。看一看在Java中实现Mixin?,java,mixins,Java,Mixins,使用Java6,我如何实现一个?这在Ruby中是非常容易和可能的。我怎样才能在Java中得到类似的东西呢?因为Java只支持单一继承,这是不可能的。看一看 编辑:由于对接口的评论:mixin最酷的一点是,您可以在不编写组合代码的情况下组合它们。对于接口,您必须自己实现组合的功能(除了一个可以扩展的类) 在Java中伪造mixin:在Ruby mixin相当于Java抽象类的意义上,不,不能在Java中实现mixin。您可以通过使用接口,从而在mix-in中完全不定义任何代码,但您无法直接实现与R
编辑:由于对接口的评论:mixin最酷的一点是,您可以在不编写组合代码的情况下组合它们。对于接口,您必须自己实现组合的功能(除了一个可以扩展的类) 在Java中伪造mixin:在Ruby mixin相当于Java抽象类的意义上,不,不能在Java中实现mixin。您可以通过使用接口,从而在mix-in中完全不定义任何代码,但您无法直接实现与Ruby mix-in中相同的行为。看一看 它使用了我创建的一组注释
注意:我正在对注释进行重大更新,其中包括一些API破坏。我计划在未来几周发布一个新版本。我想说的是只使用对象合成。每当您想要加入新功能时,请将另一个对象作为成员组合到类中。如果要使所有的混合类都具有相同的类型,可以使用数组作为成员对象,其中每个元素都由所有其他元素组成,并且可以分派到特定的元素。您可以使用它。该类能够从多个接口/对象委托生成动态类:
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)
最简单的方法是使用静态导入。它允许代码重用,“看起来”像是类的一部分,但实际上是在其他地方定义的 优点:
- 真的很容易
- 您可以“混合”任意数量的静态导入
- 静态方法将无法访问 “这个”,所以你必须通过它 手动输入
- 无状态:静态方法不能有自己的实例字段。它们只能定义自己的静态字段,然后由调用静态方法的任何对象共享
- 无法在客户机类(其中混入代码的类)上定义公共方法。在Ruby中,导入mixin实际上会将这些公共方法定义为类上的公共方法。在Java中,在这种情况下继承是更好的解决方案(假设您不需要扩展多个类)
import static my.package.MyHelperUtility.methodDefinedInAnotherClass;
public class MyNormalCode {
public void example() {
methodDefinedInAnotherClass();
}
}
刚刚遇到:(Borken链接更新)是的,在Java中实现mixins Approach最简单、最方便的方法是从包含静态方法的某个类中使用静态导入 术语“Mixin”是否不等同于面向方面编程运动中的Java术语“方面”?AspectJ可能值得一看。更新:Qi4j现在是ApachePolygene, Qi4j对mixin的定义可能非常独特,因为它不是从基类开始的。通过走极端,一种全新的应用程序构建模式出现了,我们称之为面向组合的编程。组合是“对象”等价物,不仅是连接在一起的混合,而且还有约束(验证)、关注(围绕建议)和副作用(不能改变方法结果) 所以我认为Qi4j有一个很强的混合故事要讲。mixin可以是“类型化”或“泛型”的,它们可以是公共的(可在组合外部访问),也可以是纯私有的(在组合内部)。Qi4j强烈地定义了什么是属性,并且具有内置的持久性,它不会将存储实现泄漏到您的域中(注意;Qi4j泄漏到您的域)。一旦持久化实体进入图片,还需要关联的强定义(并包含在Qi4j中) 有关良好的概述,请参阅 在Qi4j中,只有mixin具有状态。约束/关注点/副作用不能有状态(如果有,则需要引用私有mixin) 要在Qi4j中定义复合,可以在类型本身的结构上进行,也可以在创建运行时模型时在引导时进行 结构上
@mixin({PetrolEngfineMixin.class,FourWheelsMixin.class})
公共接口车扩展了发动机、车轮和实体组件
{}
开机时;
公共接口车
{}
公共类CarModuleAssembler
实现汇编程序
{
公共无效装配(模块装配模块)
{
模块实体(Car.class)
.带混合器(PetronEngineMixin.class、四轮Smixin.class);
}
}
然而,这只是触及到Qi4j中特性的表面。默认方法
我知道问题是说Java6,但在Java8中,我们有一个相当不错的选择:
我们将能够添加接口方法的“默认”实现,因此我们可以添加新方法,而不会破坏实现接口的每个类
只要mixin不需要状态,就可以在接口中编写代码。然后,您的类可以根据需要实现任意多的这些接口,然后启动
这是对制度的滥用吗?有一点,但它不会涉及任何多重继承问题,因为没有状态
当然,这也是这种方法的最大缺点。现在可以使用Java进行混合(即5,6,7)。Java 8当然会通过其defender方法添加更好的功能。不确定您要从Mixin中寻找哪些功能,但大部分功能都可以使用decorator模式完成
我正在探索为Java 7提供此功能。我的第一个切入点是使用本文中所示的示例:
public interface Human {
String hello();
String die(String age);
String eat();
String dance();
}
public interface Monkey {String hello(); String eat();}
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";
}
}
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!"