简体   繁体   English

Java接口:继承,重写和重载方法

[英]Java Interface: Inheriting, Overriding, and Overloading Methods

In "THE Java™ Programming Language, Fourth Edition" By Ken Arnold, James Gosling, David Holmes, its mentioned that: 在“The Java™Programming Language,Fourth Edition”中,Ken Arnold,James Gosling,David Holmes提到:

paragraph: (4.3.2) "Similarly, if an interface inherits more than one method with the same signature, or if a class implements different interfaces containing a method with the same signature, there is only one such method. The implementation of this method is ultimately defined by the class implementing the interfaces, and there is no ambiguity there. If the methods have the same signature but different return types, then one of the return types must be a subtype of all the others, otherwise a compile-time error occurs. The implementation must define a method that returns that common subtype." 段落:(4.3.2) “同样,如果一个接口继承了多个具有相同签名的方法,或者一个类实现了包含具有相同签名的方法的不同接口,则只有一个这样的方法。该方法的实现最终由实现接口的类定义,并且没有歧义。如果方法具有相同的签名但返回类型不同,则其中一个返回类型必须是所有其他类型的子类型,否则编译时错误实现必须定义一个返回该公共子类型的方法。“

Can anybody give me some example code that justifies the points of above paragraph ? 任何人都可以给我一些示例代码来证明上段的要点吗?

I tried to write the code and test what is mentioned but I am getting compile-time error the sub-interface hides the base interface method so can only implement sub-interface method. 我试着编写代码并测试提到的但是我得到编译时错误,子接口隐藏了基本接口方法,所以只能实现子接口方法。

Thanks in advance. 提前致谢。 -Arun -Arun

interface A {
    void method();
    Object returnMethod();
}
interface B {
    void method();
    B returnMethod();
}

class Impl implements A,B 
{
    void method() { }
    B returnMethod() { }
}

As you can see, Impl.method() implements both A.method() and B.method() , while Impl.returnMethod() returns a B , which is a child of Object , thus fulfilling A.returnMethod() 's contract too. 如您所见, Impl.method()实现了A.method()B.method() ,而Impl.returnMethod()返回一个B ,它是Object的子A.returnMethod() ,因此实现了A.returnMethod()的实现。合同也是。 Would the latter require a return type that is not a parent of B.returnMethod() 's return type that would be a comile error, since no such implementation could exist in Impl . 后者是否需要一个不是B.returnMethod()返回类型的父类的返回类型,这将是一个comile错误,因为在Impl不存在这样的实现。

In the following two interfaces methodA() is identically defined in terms of parameters (none) and return type (int). 在以下两个接口中, methodA()在参数(none)和返回类型(int)方面相同地定义。 The implementation class at the bottom defines a single method with this exact signature. 底部的实现类定义了具有此精确签名的单个方法。 As it complies to both interfaces, you get no problem there - any calls made via a reference of type InterfaceA or InterfaceB will be dispatched to this implementation. 由于它符合两个接口,因此您不会遇到任何问题 - 通过InterfaceA或InterfaceB类型的引用进行的任何调用都将被分派到此实现。

The second methodB() is defined as returning any subtype of Number (or Number itself) in InterfaceA . 第二个方法methodB()被定义为在InterfaceA返回Number (或Number本身)的任何子类型。 InterfaceB defines methodB() as returning an Integer which is a subtype of Number . InterfaceBmethodB()定义为返回一个Integer ,它是Number的子类型。 The implementation class actually implements the method with Integer , thus complying to the contract of both InterfaceA and InterfaceB . 实现类实际上使用Integer实现该方法,因此遵守InterfaceAInterfaceB的约定。 No problem here either. 这里也没问题。 The commented out case of methodB() being implemented as returning a Double however would not work: While it would satisfy the contract of InterfaceA , it would conflict with InterfaceB (which demands an Integer ). 注释掉的methodB()被实现为返回一个Double情况不会起作用:虽然它会满足InterfaceA的契约,但它会与InterfaceB (它需要一个Integer )冲突。

If InterfaceA and InterfaceB were also specifying (different) contracts for a methodC() (commented out in the example) this would be contradictory and create a compiler error. 如果InterfaceAInterfaceB也为methodC() (在示例中注释掉)指定(不同的)契约,那么这将是矛盾的并且会产生编译器错误。 Implementing both signatures (differing only in return type) is not allowed in Java. 在Java中不允许实现两个签名(仅在返回类型上不同)。

The above rules would also hold true if were to add any parameters to the methods. 如果要向方法添加任何参数,上述规则也适用。 For simplicity I kept this out of the example. 为简单起见,我保留了这个例子。

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;
    // }
}
/**
 * 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
                }
        }
}
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()
   {
      ...
   }
}

Is this what you mean?: 你是这个意思吗?:

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

Such a method in MyClass is automatically generated by javac as a synthetic bridge method. MyClass中的这种方法由javac自动生成为合成桥接方法。 You must implement a single method returning a type compatible with all of the implemented/overridden methods (in this case Number / Integer / Double /etc). 您必须实现一个返回与所有已实现/重写的方法兼容的类型的方法(在本例中为Number / Integer / Double / etc)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM