【问题标题】:Java Interface: Inheriting, Overriding, and Overloading MethodsJava 接口:继承、覆盖和重载方法
【发布时间】:2009-05-18 12:53:58
【问题描述】:

在 Ken Arnold、James Gosling、David Holmes 撰写的“THE Java™ 编程语言,第四版”中,提到:

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

谁能给我一些示例代码来证明上述段落的观点?

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

提前致谢。 -阿伦

【问题讨论】:

  • 张贴你的代码和你的编译器错误老兄......至少给我们一些东西来(a)重现这个问题; (b) 从那里开始。
  • 大家真的很抱歉 - 我试图使用 j2sdk1.4.2_08 测试上面提到的段落中提到的内容 - 我没有意识到这本书是为 JDK1.5 编写的所以这意味着如果您使用 JDK1.4 由“Daniel Schneller”编译代码 sn-p,您将得到“ImplementationOfAandB.java:17: methodB() in ImplementationOfAandB cannot implement methodB() in InterfaceA;尝试使用不兼容的返回类型”编译错误而JDK1.5运行良好。

标签: java interface overriding overloading


【解决方案1】:
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 中不存在这样的实现。

【讨论】:

  • 那是 C# 吗?问题是关于 Java 的。
  • 我认为使用哪种语言并不重要 ;)
  • 不,Impl 必须实现更具体的返回类型才能满足这两个接口。
【解决方案2】:

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

第二个methodB() 定义为在InterfaceA 中返回Number(或Number 本身)的任何子类型。 InterfaceBmethodB() 定义为返回 Integer,它是 Number 的子类型。实现类实际上实现了Integer的方法,因此同时遵守InterfaceAInterfaceB的约定。这里也没有问题。 注释掉的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;
    // }
}

【讨论】:

  • 大家真的很抱歉 - 我试图使用 j2sdk1.4.2_08 测试上面提到的段落中提到的内容 - 我没有意识到这本书是为 JDK1.5 编写的所以这意味着如果您使用 JDK1.4 通过“Daniel Schneller”编译代码 sn-p,您将得到“ImplementationOfAandB.java:17: methodB() in ImplementationOfAandB cannot implement methodB() in InterfaceA;尝试使用不兼容的返回类型”编译错误而JDK1.5运行良好。
【解决方案3】:
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()
   {
      ...
   }
}

【讨论】:

    【解决方案4】:

    这是你的意思吗?:

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

    【讨论】:

      【解决方案5】:
      /**
       * 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
                      }
              }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-09-19
        • 1970-01-01
        • 2013-08-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多