下面是一个简单的例子,展示了我的问题:
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");
}
}
在SingleWG
中,我提供了方法get
和size
的实现,这是来自AbstractList
的唯一抽象方法。但是,当我编译MyWork
时,我仍然会遇到以下错误:
类型MyWork必须实现继承的抽象方法AbstractCollection.size()
或者
我的任务。java:3:错误:MyTask不是抽象的,并且不重写AbstractList中的抽象方法get(int)
(取决于编译器)。当然,我使用的是java 8。
所以我有两个问题:
MyWork
中使用这两个方法的最简单方法是什么?我认为@biziclop在他的回答中正确地涵盖了这一点。简而言之,由于AbstractList
将get(int)
和size()
方法声明为抽象方法,因此它们优先于SingleTask
中的默认实现。
最简单的方法是重写MyWG
中的get(int)
和size()
方法,以便它们委托给您在SingleWG
接口中的默认方法:
public class MyTask extends AbstractList<Runnable> implements SingleTask {
@Override
public void run() {
System.out.println("hello");
}
@Override
public Runnable get(int index) {
return SingleTask.super.get(index);
}
@Override
public int size() {
return SingleTask.super.size();
}
}
使用这种方法,您将有点委托给SingleTask
中的默认方法。我不认为这是一件坏事(至少,您不需要使用属性)。此外,编写这些方法是有意义的,这样您就可以选择提供默认实现的接口。
强制SingleTask
实现者也实现List
的所有方法不是很优雅,默认方法也不是用来定义你的SingleTask
界面看起来像的特征实体。
默认方法作为特征是一个坏主意,有几个原因,最明显的一个是任何实现者都可以简单地覆盖你的默认方法,破坏你的特征。
这正是这里正在发生的事情:因为AbstractList
显式声明get()
和size()
为抽象
,这意味着SingleWG
将继承它们,而不是您的默认实现可能有一个超级界面。
JLS 8.4.8:
类C从其直接超类和直接超接口继承所有抽象和默认(§9.4)方法m,对于这些方法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();
}
它的缺点是您的任务必须扩展SingleTask
,因此不能扩展任何其他内容,从好的方面来说,虽然它们不需要处理任务,但它们也是列表
,它们只需要实现run()
。
但是从长远来看,我更喜欢组合而不是继承,任务只是返回一个可运行的列表,而不是它们本身。
本文向大家介绍Kotlin 与默认实现接口,包括了Kotlin 与默认实现接口的使用技巧和注意事项,需要的朋友参考一下 示例 Kotlin中的接口可以具有功能的默认实现: 实现此类接口的类将能够使用这些功能而无需重新实现 物产 默认实现也适用于属性获取器和设置器: 接口访问器实现不能使用后备字段 多种实现 当多个接口实现相同的功能,或者所有接口都定义一个或多个实现时,派生类需要手动解析正确的调用
我遵循本指南https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-8.0/default-interface-methods使用默认接口实现功能。我复制了一段在接口中定义默认实现的代码,然后在接口中重写它: 但它给出了一个错误和一个警告。设置为,为。为什么即使在官方文件中有描述也不起作用
本文向大家介绍我们是否必须在实现Java接口的类中实现所有方法?,包括了我们是否必须在实现Java接口的类中实现所有方法?的使用技巧和注意事项,需要的朋友参考一下 是的,必须在实现接口的类中实现所有方法,直到并且除非该类被声明为抽象类。 只有两个选择- 实现接口定义的每个方法。 将该类声明为抽象类,结果迫使您在创建任何对象之前先对该类进行子类化(并实现缺少的方法)。 类不需要在接口中实现所有方法的
我想避免在maven插件swagger codecen生成的接口中实现“默认”。例如,使用petstore swagger:http://petstore.swagger.io/v2/swagger.json 我用maven插件生成接口: 我生成类似PetApi的接口。具有默认方法实现的java: 我想尽量避免 有可能做到吗? 2020年3月更新: 根据新的OpenAPI工具 有一个带有的选项(已
问题内容: 向所有Java专家致敬! 从Java8开始,我们可以在接口中使用默认实现(是的!)。但是,当您想从默认方法登录时会出现问题。 我有种感觉,每次我想在默认方法中记录某些内容时都调用.getLogger()是不明智的。 是的,可以在接口中定义静态变量-但这对于接口而言不是一个好习惯,而且+暴露了记录器(必须是公开的)。 我目前的解决方案: LogHolder仍然对所有人可见,这实际上没有任
问题内容: 考虑以下情况, 在上面的例子中我得到以下输出这是 相当 期待。 我一直在阅读有关默认方法的信息, 尤其是 关于扩展包含默认方法的接口的信息 2 第二子弹:重新声明的默认方法,这使得它的抽象。 在上面的示例中,我有两个接口的默认方法具有相同的名称,并且当我实现这两个接口时,我只能实现对的引用。 我对此几乎没有疑问, 我怎样才能 到达 的方法 和 如果我不能比,为什么? 没有这种行为从本质