2009-05-18 63 views
7

在“Java™编程语言,第四版”通过根·阿诺德,詹姆斯·高斯林,大卫·霍姆斯,它提到:Java接口:继承,替换,重载方法

款:(4.3.2) “同样,如果一个接口继承了具有相同签名的多个方法,或者一个类实现了包含具有相同签名的方法的不同接口,那么只有一个这样的方法。实现接口的类,并且没有歧义,如果方法具有相同的签名但返回类型不同,则其中一种返回类型必须是所有其他类型的子类型,否则发生编译时错误。实现必须定义一个返回普通型的方法“。

任何人都可以给我证明前款点一些示例代码?

我试着写代码和测试的内容被提及但我收到编译时错误 子接口隐藏了基接口方法,因此只能实现子接口的方法。

在此先感谢。 -Arun

+0

你能显示代码? – 2009-05-18 12:59:49

+1

发布你的代码和你的编译器错误的家伙......至少给我们一些(a)重现问题;和(b)从那里出发。 – corlettk 2009-05-18 13:00:44

+0

每个人我都很抱歉 - 我试图用j2sdk1.4.2_08测试上面提到的段落中提到的内容 - 我没有意识到这本书是为JDK1.5编写的 所以这意味着如果你编译代码片段通过使用JDK1.4的“Daniel Schneller”,你将在ImplementationOfAandB中得到一个“ImplementationOfAandB.java:17:methodB()”,但不能在InterfaceA中实现methodB();尝试使用不兼容的返回类型“编译错误,而使用JDK1.5它只运行精细。 – akjain 2009-05-18 14:24:50

回答

2

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

第二methodB()被定义为InterfaceA返回的Number(或Number本身)的任何亚型。 InterfaceBmethodB()定义为返回Integer,其是Number的子类型。实现类实际上实现了Integer的方法,因此符合01​​和InterfaceB的合同。这里也没有问题。 的methodB()注释掉的情况下被实现为返回Double不过是行不通的:虽然这将满足InterfaceA合同,它将与InterfaceB冲突(这需要一个Integer)。

如果InterfaceAInterfaceB也为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; 
    // } 
} 
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() 
    { 
     ... 
    } 
} 
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()的返回类型的父类型,这将是一个comile错误,因为在Impl中不存在这样的实现。

+0

但Impl必须实现对象ReturnMethod(),对吗? – 2009-05-18 13:05:10

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)。

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 
       } 
     } 
}