【发布时间】:2016-06-16 15:38:15
【问题描述】:
这是一个显示我的问题的简化示例:
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");
}
}
在SingleTask 中,我提供了get 和size 方法的实现,它们是AbstractList 中仅有的抽象方法。但是,当我编译 MyTask 时,我仍然会收到如下错误:
MyTask 类型必须实现继承的抽象方法 AbstractCollection.size()
或
MyTask.java:3: 错误:MyTask 不是抽象的并且不会覆盖 AbstractList 中的抽象方法 get(int)
(取决于编译器)。当然,我使用的是 java 8。
所以我有两个问题:
- 为什么会出现这些错误?我期待它能够识别默认实现。
- 如果不应该这样工作,那么在不复制整个代码的情况下,在
MyTask中使用这两种方法的最简单方法是什么?
【问题讨论】:
-
不要让你的任务扩展
List<Runnable>(这在语义上意味着什么?),而是使用public List<Runnable> getRunnables();方法创建一个接口Task。如果做不到这一点,只需将SingleTask设为抽象类而不是接口。 -
值得注意的是,Eclipse 在
size()未实现时感到窒息:这可能是一个 Eclipse 错误。javac1.8.0_51 因get(int)未实施而窒息,这是正确的:未实施。 -
@Tunaki
size和get同样实现/未实现 -
@aditsu
SingleTask is a singleton implementation好了,你刚刚说了。如果它是一个实现,它应该是一个类,而不是一个接口。你在这里尝试使用默认方法的东西看起来有点像特征,它们不是为它设计的。 -
如果这行得通,你会得到一个
List实现,其中甚至像equals或hashCode这样的关键方法也会被破坏,因为它们最终可能会得到StackOverflowError。这种递归数据结构的意义何在?
标签: java java-8 default-method