在“The Java™Programming Language,Fourth Edition”中,Ken Arnold,James Gosling,David Holmes提到:
段落:(4.3.2) “类似地,如果一个接口继承了多个具有相同签名的方法,或者一个类实现了包含具有相同签名的方法的不同接口,则只有一个这样的方法。此方法的实现最终由实现接口的类,并没有歧义。如果方法具有相同的签名但返回类型不同,则其中一个返回类型必须是所有其他类型的子类型,否则会发生编译时错误。必须定义一个返回该公共子类型的方法。“
有人能给我一些示例代码来证明上段的要点吗?
我尝试编写代码并测试提到的内容但是我遇到了编译时错误 子接口隐藏了基接口方法,因此只能实现子接口方法。
提前致谢。 -Arun
答案 0 :(得分:8)
interface A {
void method();
Object returnMethod();
}
interface B {
void method();
B returnMethod();
}
class Impl implements A,B
{
void method() { }
B returnMethod() { }
}
如您所见,Impl.method()
同时实现了A.method()
和B.method()
,而Impl.returnMethod()
则返回B
,这是Object
的子项因此也符合A.returnMethod()
的合同。后者是否需要一个返回类型,该类型不是B.returnMethod()
的返回类型的父类,这将是一个漫游错误,因为Impl
中不存在这样的实现。
答案 1 :(得分:2)
在以下两个接口methodA()
中,参数(none)和返回类型(int)的定义相同。底部的实现类定义了具有此精确签名的单个方法。因为它符合两个接口,所以你没有遇到任何问题 - 通过InterfaceA或InterfaceB类型的引用进行的任何调用都将被分派到这个实现。
第二个methodB()
被定义为在Number
中返回Number
(或InterfaceA
本身)的任何子类型。 InterfaceB
将methodB()
定义为返回Integer
,它是Number
的子类型。实现类实际上使用Integer
实现方法,因此遵守InterfaceA
和InterfaceB
的约定。这里也没问题。
然而,methodB()
被注释为返回Double
的被注释的情况不起作用:虽然它会满足InterfaceA
的合同,但它会与InterfaceB
冲突(需要Integer
InterfaceA
)。
如果InterfaceB
和methodC()
也为public interface InterfaceA {
public int methodA();
public Number methodB();
// public int methodC(); // conflicting return type
}
public interface InterfaceB {
public int methodA();
public Integer methodB();
// public String methodC(); // conflicting return type
}
public class ImplementationOfAandB implements InterfaceA, InterfaceB {
public int methodA() {
return 0;
}
public Integer methodB() {
return null;
}
// This would NOT work:
// public Double methodB() {
// return null;
// }
}
(在示例中注释掉)指定(不同)合同,则这将是矛盾的并且会产生编译器错误。 Java中不允许实现这两个签名(仅在返回类型上有所不同)。
如果要向方法添加任何参数,上述规则也适用。为简单起见,我保留了这个例子。
{{1}}
答案 2 :(得分:1)
interface A
{
void foo();
//int bar(); <-- conflicts with B.bar() because of different return type
}
interface B
{
void foo();
//double bar(); <-- conflicts with A.bar() because of different return type
}
class C implements A, B
{
void foo() // this implements A.foo() AND B.foo()
{
...
}
}
答案 3 :(得分:1)
这是你的意思吗?:
interface A {
Object get();
}
interface B {
Number get();
}
abstract class MyClass implements A, B {
// Try to override A.get, but cause a compile error.
public Object get() { return null; }
}
MyClass中的这种方法由javac自动生成为合成桥接方法。您必须实现一个方法,返回与所有已实现/重写的方法兼容的类型(在本例中为Number
/ Integer
/ Double
/ etc)。
答案 4 :(得分:1)
/**
* This is what you have
*/
interface IXR {
//bla-bla-bla
}
class CXR implements IXR {
//concrete implementation of bla-bla-bla
}
interface IX {
public IXR f();
}
interface IYR {
//some other bla-bla-bla
}
class CYR implements IYR {
//concrete implementation of the some other bla-bla-bla
}
interface IY {
public IYR f();
}
/**
* This is what you need to add
*/
interface IZR extends IXR, IYR {
//EMPTY INTERFACE
}
class CZXR extends CXR implements IZR {
//EMPTY CLASS
}
class CZYR extends CYR implements IZR {
//EMPTY CLASS
}
class CZ implements IX, IY
{
public static boolean someCondition = true;
public IXR implementationOf_X_f()
{
System.out.println("CXR");
return new CZXR();
}
public IYR implementationOf_Y_f()
{
System.out.println("CYR");
return new CZYR();
}
public IZR f() {
if (someCondition) {
return (IZR) implementationOf_X_f();
} else {
return (IZR) implementationOf_Y_f();
}
}
}
/**
* This is the usage of the required class
*/
class program
{
public static void main(String[] x) {
CZ o = new CZ();
IZR r = o.f();
if (CZ.someCondition) {
CXR xr = (CXR) r;
//bla-bla-bla
} else {
CYR yr = (CYR) r;
//bla-bla-bla
}
}
} /**
* This is what you have
*/
interface IXR {
//bla-bla-bla
}
class CXR implements IXR {
//concrete implementation of bla-bla-bla
}
interface IX {
public IXR f();
}
interface IYR {
//some other bla-bla-bla
}
class CYR implements IYR {
//concrete implementation of the some other bla-bla-bla
}
interface IY {
public IYR f();
}
/**
* This is what you need to add
*/
interface IZR extends IXR, IYR {
//EMPTY INTERFACE
}
class CZXR extends CXR implements IZR {
//EMPTY CLASS
}
class CZYR extends CYR implements IZR {
//EMPTY CLASS
}
class CZ implements IX, IY
{
public static boolean someCondition = true;
public IXR implementationOf_X_f()
{
System.out.println("CXR");
return new CZXR();
}
public IYR implementationOf_Y_f()
{
System.out.println("CYR");
return new CZYR();
}
public IZR f() {
if (someCondition) {
return (IZR) implementationOf_X_f();
} else {
return (IZR) implementationOf_Y_f();
}
}
}
/**
* This is the usage of the required class
*/
class program
{
public static void main(String[] x) {
CZ o = new CZ();
IZR r = o.f();
if (CZ.someCondition) {
CXR xr = (CXR) r;
//bla-bla-bla
} else {
CYR yr = (CYR) r;
//bla-bla-bla
}
}
}