9

在 Ken Arnold、James Gosling、David Holmes 撰写的“THE Java™ Programming Language, Fourth Edition”中,它提到:

段落:(4.3.2) “同样,如果一个接口继承了多个具有相同签名的方法,或者如果一个类实现了包含具有相同签名的方法的不同接口,则只有一个这样的方法。该方法的实现最终由实现接口的类定义,没有歧义。如果方法具有相同的签名但返回类型不同,则返回类型必须是所有其他类型的子类型,否则编译时错误发生。实现必须定义一个返回该公共子类型的方法。

任何人都可以给我一些示例代码来证明上述段落的观点吗?

我尝试编写代码并测试所提到的内容,但出现编译时错误,子接口隐藏了基本接口方法,因此只能实现子接口方法。

提前致谢。-阿伦

4

5 回答 5

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()and B.method(),同时Impl.returnMethod()返回 a B,它是 的子级Object,因此也履行了A.returnMethod()'s 合同。后者是否需要一个不是返回类型的父级B.returnMethod()的返回类型,这将是一个comile错误,因为在Impl.

于 2009-05-18T13:01:42.197 回答
2

以下两个接口methodA()在参数(none)和返回类型(int)方面定义相同。底部的实现类定义了一个具有这个确切签名的方法。由于它同时符合这两个接口,因此您不会遇到任何问题 - 通过 InterfaceA 或 InterfaceB 类型的引用进行的任何调用都将被分派到此实现。

第二个被定义methodB()为返回. 定义为返回一个which 是 的子类型。实现类实际上实现了 with 的方法,因此符合and的约定。这里也没有问题。注释掉的被实施为返回 a然而的情况是行不通的:虽然它会满足 的合同,但它会与(要求 a )冲突。NumberNumberInterfaceAInterfaceBmethodB()IntegerNumberIntegerInterfaceAInterfaceBmethodB()DoubleInterfaceAInterfaceBInteger

如果InterfaceA并且还为(在示例中注释掉的InterfaceB)指定(不同的)合约,这将是矛盾的,并会产生编译器错误。methodC()Java 中不允许同时实现这两个签名(仅在返回类型上有所不同)。

如果要向方法添加任何参数,上述规则也适用。为简单起见,我将其排除在示例之外。

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;
    // }
}
于 2009-05-18T13:15:18.830 回答
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()
   {
      ...
   }
}
于 2009-05-18T13:01:10.420 回答
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/ Doubleetc)。

于 2009-05-18T13:08:06.380 回答
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
                }
        }
}
于 2011-09-07T11:48:02.183 回答