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 |