问题 如何实现有效的Java特性?


如果这是不合适的,请告诉我(特别是Programmers.SE或者某些东西对于这个问题会更好。)

好的。所以我有很多'特征',我目前正在表达为接口。我们称之为“可更新”和“可破坏”。将它们表示为接口有一个缺点,我无法在所有“可破坏”组件之间共享行为;另一方面,将这些表示为抽象类意味着我不能混合和匹配而不将混合特征明确定义为另一个抽象类(“UpdateableAndDestructible”),而且这感觉就像滥用抽象类功能一样。但是,如果没有更清晰的方法来解决这个问题,我可能最终会这样做。

对于这个难题,纯Java解决方案有哪些选择?我是否有可能描述共享行为,然后按照我认为合适的方式进行混合和匹配,而不必明确描述我将要使用的每个排列?


8148
2017-08-22 18:44


起源

你在说 混入  - 如果您正在进行搜索,这可能是一个有用的术语。 - Jesper


答案:


也许你可以通过使用混合的接口和默认实现来实现目标。

喜欢:

public interface Updatable {
  void updated();
}

public interface Loadable {
  void load();
}

public class DefaultUpdatable implements Updatable {
 ...
}

public class DefaultLoadable implements Loadable {
 ...
}

public class SomeObject implements Updatable, Loadable {
  private final Updatable updatable = new DefaultUpdatable();
  private final Loadable loadable = new DefaultLoadable();

  public void load() {
    this.loadable.load();
  }

  public void updated() {
    this.updatable.updated();
  }
}

仍然很嘈杂,可能没有你想要的那么灵活,但可能比做UpdatableAndDestructable更清洁。


6
2017-08-22 19:00



+1并接受,这是处理问题的明智方法。 (顺便提一下,在调查这个问题的时候,我发现了一些像Guice这样有用的框架,这使得使用这种逻辑变得不那么痛苦了。) - Joseph Weissman


我不认为这个问题有一个漂亮的解决方案,但可能有一些可行的解决方案取决于你多么鄙视样板。

您可以将特征定义为另一个类+接口,它将实例对象作为第一个参数。并且它们实现了与您想要具有特征的类的接口。然后创建调用特征impl上的方法的存根方法。

public class MyClass implements MyTrait {
    @Override
    public void doSomething() {
        MyTraitImpl.doSomething(this);
    }
}

然后是特质本身:

public interface MyTrait {
    public void doSomething();
}

public class MyTraitImpl {
    public static void doSomething(MyTrait obj) {
        // do something with obj
    }
}

正如Ernest Friedman-Hill所说,Scala为你做了这件事(据我所知,这就是它如何在JVM上实现特征)。


5
2017-08-22 19:05





我知道你说的是“纯Java”,但这是件事 斯卡拉 做得好Java语言本身的局限性是人们采用其他JVM语言的强大动力......


4
2017-08-22 18:54



谢谢你的建议。 - Joseph Weissman


如果您考虑使用 龙目岛 作为纯Java,您可以通过使用来简化您的生活 @Delegate 喜欢这个:

public class SomeObject implements Updatable, Loadable {
    @Delegate private final Updatable updatable = new DefaultUpdatable();
    @Delegate private final Loadable loadable = new DefaultLoadable();
}

1
2017-08-22 22:08