adi*_*tsu 5 java java-8 default-method
这是一个显示我的问题的简化示例:
import java.util.List;
public interface SingleTask extends List<Runnable>, Runnable {
default Runnable get(final int x) {
if (x != 0) {
throw new IndexOutOfBoundsException();
}
return this;
}
default int size() {
return 1;
}
}
import java.util.AbstractList;
public class MyTask extends AbstractList<Runnable> implements SingleTask {
@Override
public void run() {
System.out.println("hello");
}
}
Run Code Online (Sandbox Code Playgroud)
在SingleTask我提供用于方法的实现get和size,它们是从仅抽象方法AbstractList.但是,当我编译时MyTask,我仍然会遇到如下错误:
MyTask类型必须实现继承的抽象方法AbstractCollection.size()
要么
MyTask.java:3:错误:MyTask不是抽象的,并且不会覆盖AbstractList中的抽象方法get(int)
(取决于编译器).我当然是使用java 8.
所以我有两个问题:
MyTask不复制整个代码的情况下使用这两种方法的最简单方法是什么?强制SingleTask实现者也实现所有方法List都不是很优雅,并且默认方法不能用于定义类似特征的实体,您的SingleTask界面看起来就像.
有几个原因导致默认方法 - 特征是一个坏主意,最明显的是任何实现者都可以简单地覆盖你的默认方法,破坏你的特性.
这正是这里发生的事情:因为AbstractList显式声明get()和size()as abstract,它意味着SingleTask将继承它们,而不是你在超级接口中可能拥有的默认实现.
类C继承自其直接超类和直接超接口所有抽象和默认(§9.4)方法m,其中所有以下都是真的:
...
- C从其直接超类继承的具体方法没有签名,该签名是m的签名的子签名.
记住所有这些最简单的解决方案可能是这样的:
public abstract class SingleTask extends AbstractList<Runnable> implements Runnable {
@Override
public final Runnable get(final int x) {
if (x != 0) {
throw new IndexOutOfBoundsException();
}
return this;
}
@Override
public final int size() {
return 1;
}
@Override
public abstract void run();
}
Run Code Online (Sandbox Code Playgroud)
它的缺点是你的任务必须扩展SingleTask,因此不能扩展任何其他东西,虽然他们不需要处理任务也是一个优点List,他们只需要实现run().
从长远来看,我更喜欢组合而不是继承,而任务只是返回一个runnables列表,而不是自己是一个.
| 归档时间: |
|
| 查看次数: |
477 次 |
| 最近记录: |