Java8-两个接口包含具有相同方法签名但不同返回类型的默认方法,如何重写?
我理解,如果一个类实现了多个包含相同名称的默认方法的接口,那么我们需要在子类中重写该方法,以便显式定义我的方法将执行的操作。Java8-两个接口包含具有相同方法签名但不同返回类型的默认方法,如何重写?,java,interface,java-8,overriding,default-method,Java,Interface,Java 8,Overriding,Default Method,我理解,如果一个类实现了多个包含相同名称的默认方法的接口,那么我们需要在子类中重写该方法,以便显式定义我的方法将执行的操作。问题是,请参阅以下代码: interface A { default void print() { System.out.println(" In interface A "); } } interface B { default String print() { return "In interface B";
问题是,请参阅以下代码:
interface A {
default void print() {
System.out.println(" In interface A ");
}
}
interface B {
default String print() {
return "In interface B";
}
}
public class C implements A, B {
@Override
public String print() {
return "In class C";
}
public static void main(String arg[]) {
// Other funny things
}
}
现在,接口A和B都有一个名为“print”的默认方法,但我想重写接口B的print方法,即返回字符串并保持A的print不变的方法。但这段代码不会编译,因为:
Overrides A.print
The return type is incompatible with A.print()
很明显,编译器试图重写A的print方法,我不知道为什么 这是不可能的
:
如果返回类型为R1的方法声明d1
覆盖或隐藏另一个返回类型为R2的方法声明d2
,则d1
必须是可替换为d2的返回类型,否则会发生编译时错误
:
返回类型为R1的方法声明d1
,如果满足以下任一条件,则返回类型可替换为返回类型为R2的另一方法d2
:
- 如果
为R1
则void
为R2
void
- 如果
是基本类型,则R1
与R2
相同R1
- 如果
是参考类型,则以下情况之一为真:R1
,适用于R1
的类型参数,是d2
的一个子类型R2
可以通过未选中的转换转换转换为R1
的子类型R2
与d1
和d2
没有相同的签名R1=| R2
void
、原语和引用返回方法只能重写相同类别的方法,并且只能被相同类别的方法重写。void
方法只能重写另一个void
方法,引用返回方法只能重写另一个引用返回方法,依此类推
您遇到的问题的一个可能解决方案是使用组合而不是继承:
class C {
private A a = ...;
private B b = ...;
public A getA() { return a; }
public B getB() { return b; }
}
疯狂的想法:改变“工具”的顺序list@flowtron我的第一个直觉也是一样,不起作用。也许一个实现了a并将其print定义为final的类可以让你达到目的。。另一个疯狂的想法。@flowtron当然有其他的解决方法,但我想知道为什么这个功能是这样设计的。我主要关心的是覆盖接口B的“print()”方法,您提到的链接非常清楚地表明:
如果C类继承了一个具体方法,其签名与C继承的另一个方法的重写等效,则这是一个编译时错误。
因此我理解“发生了什么”,但“为什么”仍然不清楚!为什么编译器不能通过方法的签名识别我正在重写接口B的print()方法。或者你能告诉我为什么这是一种不好的做法吗?@Radiodef:这可能是类文件格式。所以,是的,没有技术上的原因。@RamanVerma:因为Java甚至不允许类C
同时实现A
和B
,所以它是否能够识别覆盖的方法是无关紧要的。原因是它无法识别您在说someInstanceOfC.print()
时调用的方法,至少在某种程度上不能不更改语言规则,Java设计者不希望这样做。@Eugene:在我看来,它与原始Java语言的所有其他设计决策保持一致,以使其简单且不易出错。即使在当前存在目标类型的版本中,根据预期的返回类型在不同的方法中进行选择也不是一个好主意。只需再添加一个方面:根据返回类型选择方法肯定不适合协变返回类型。继承一个返回Number
的方法和另一个返回Integer
的方法会产生相当模糊的问题。如果您覆盖了整数
-返回方法,那么它会自动覆盖数字
-返回方法吗,还是会以两种方法结束?我很高兴这种混乱局面没有得到支持。