Java 接口:继承、覆盖和重载方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/877587/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 14:11:49  来源:igfitidea点击:

Java Interface: Inheriting, Overriding, and Overloading Methods

javainterfaceoverridingoverloading

提问by akjain

In "THE Java? Programming Language, Fourth Edition" By Ken Arnold, James Gosling, David Holmes, its mentioned that:

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

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

提前致谢。-阿伦

采纳答案by Daniel Schneller

In the following two interfaces methodA()is identically defined in terms of parameters (none) and return type (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.

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

The second methodB()is defined as returning any subtype of Number(or Numberitself) in InterfaceA. InterfaceBdefines methodB()as returning an Integerwhich is a subtype of Number. The implementation class actually implements the method with Integer, thus complying to the contract of both InterfaceAand InterfaceB. No problem here either. The commented out case of methodB()being implemented as returning a Doublehowever would not work: While it would satisfy the contract of InterfaceA, it would conflict with InterfaceB(which demands an Integer).

所述第二methodB()被定义为返回的任何亚型Number(或Number本身)InterfaceAInterfaceB定义methodB()为返回 ,Integer它是 的子类型Number。实现类实际上实现了 with 的方法Integer,从而遵守了InterfaceAand的约定InterfaceB。这里也没有问题。被注释掉的methodB()被实施为返回 a 的Double情况是行不通的:虽然它会满足 的合同InterfaceA,但它会与InterfaceB(需要Integer)发生冲突。

If InterfaceAand InterfaceBwere also specifying (different) contracts for a methodC()(commented out in the example) this would be contradictory and create a compiler error. Implementing both signatures (differing only in return type) is not allowed in Java.

如果InterfaceA并且InterfaceB还为methodC()(在示例中注释掉的)指定(不同的)合同,这将是矛盾的并会产生编译器错误。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;
    // }
}

回答by David Schmitt

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

如您所见,同时Impl.method()实现A.method()and B.method(),而Impl.returnMethod()返回 a B,它是 的子代Object,因此也实现了A.returnMethod()的合约。后者是否需要一个不是 的返回类型的父级B.returnMethod()的返回类型,这将是一个错误,因为Impl.

回答by ColdWind

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

回答by Tom Hawtin - tackline

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. You must implement a single method returning a type compatible with all of the implemented/overridden methods (in this case Number/Integer/Double/etc).

MyClass中的这样一个方法是javac自动生成的合成桥接方法。您必须实现一个方法,返回一个与所有实现/覆盖的方法兼容的类型(在这种情况下Number/ Integer/ Double/etc)。

回答by Mnementh

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