Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中实现Mixin?_Java_Mixins - Fatal编程技术网

在Java中实现Mixin?

在Java中实现Mixin?,java,mixins,Java,Mixins,使用Java6,我如何实现一个?这在Ruby中是非常容易和可能的。我怎样才能在Java中得到类似的东西呢?因为Java只支持单一继承,这是不可能的。看一看 编辑:由于对接口的评论:mixin最酷的一点是,您可以在不编写组合代码的情况下组合它们。对于接口,您必须自己实现组合的功能(除了一个可以扩展的类) 在Java中伪造mixin:在Ruby mixin相当于Java抽象类的意义上,不,不能在Java中实现mixin。您可以通过使用接口,从而在mix-in中完全不定义任何代码,但您无法直接实现与R

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

因为Java只支持单一继承,这是不可能的。看一看


编辑:由于对接口的评论: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提供此功能。我的第一个切入点是使用本文中所示的示例:

它应该与Java6一起工作,它与上面的其他注入选项类似。根据我在C#和Ruby中使用mixin的经验,您应该以实现mixin为目标,而不仅仅是模仿或伪造它

另一种型号是与以下部件一起使用的:

如果您可以使用新的Java8版本,那么可以说 @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 ); } }
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!"