关于接口:如何实现有效的Java特性?

Ways to achieve effective Java traits?

请告诉我这是否不合适(特别是programmer.se或其他什么东西对这个问题更好。)

好吧。所以我有很多"特性",我现在把它们表示为接口。让我们称之为"可更新"和"可销毁"。将它们表示为接口有一个缺点,那就是我不能在所有"可销毁"组件之间共享行为;另一方面,将它们表示为抽象类意味着,如果不将混合特性明确定义为另一个抽象类("可更新和可销毁"),我就无法混合和匹配,而且这感觉像是对abst的滥用。在这一点上,获取类功能。不过,如果没有更干净的方法来处理这个问题,我最终可能会这么做。

对于这个难题,纯Java解决方案的选择是什么?我是否可以描述共享行为,然后在我认为合适的情况下进行混合和匹配,而不必显式地描述我将要使用的每种排列?


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

像:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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();
  }
}

仍然吵闹,也许不像你想的那么灵活,但也许比做可更新和可破坏的事情要干净一点。


我认为这个问题没有一个很好的解决方案,但可能有一些可行的方案取决于你有多鄙视样板文件。

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

1
2
3
4
5
6
public class MyClass implements MyTrait {
    @Override
    public void doSomething() {
        MyTraitImpl.doSomething(this);
    }
}

然后对于特性本身:

1
2
3
4
5
6
7
8
9
public interface MyTrait {
    public void doSomething();
}

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

正如Ernest Friedman Hill所说,tho,scala是为您做的(据我所知,这就是它如何在JVM上实现特性)。


我知道你说"纯爪哇",但这是斯卡拉做的很好。Java语言本身的局限性是人们采用其他JVM语言的强大驱动力。


如果您认为使用龙目岛作为纯Java,您可以通过使用EDCOX1×0这样的方式简化您的生活:

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