Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 两个接口具有相同的方法名和不同的返回类型_Java_Oop - Fatal编程技术网

Java 两个接口具有相同的方法名和不同的返回类型

Java 两个接口具有相同的方法名和不同的返回类型,java,oop,Java,Oop,这个问题是为了理解Java中的接口。 下面是一个用Java实现接口的非常简单的示例 interface ParentA { void display(); } interface ParentB { int display(); } class Child implements ParentA, ParentB { @Override public void display() { System.err.println("Child Paren

这个问题是为了理解Java中的接口。 下面是一个用Java实现接口的非常简单的示例

interface ParentA {
    void display();
}

interface ParentB {
    int display();
}

class Child implements ParentA, ParentB {
    @Override
    public void display() {
        System.err.println("Child ParentA");
    }
    //ERROR : The return type is incompatible with ParentB.display()

    //So added method with int return type too
    @Override
    public int display() {
        System.err.println("Child ParentB");
    }
}
这种情况可能发生在大型Java应用程序中,其中两个接口可以有同名的方法。 我认为,由于返回类型不同,JVM将知道我们要覆盖哪个接口的方法

对此最好的解释是什么?这种情况有意义吗


提前感谢

在同一类中不可能有两个具有相同签名和不同返回类型的方法

签名的定义:

方法名称和参数列表的组合

发生这种情况是因为jvm不可能在两种方法之间进行选择,而只选择与返回类型不同的方法。jvm事实只能调查方法的名称和调用的参数类型

因此,您的示例在java中是不可能的

可能您必须创建两个类,一个用于接口。

因为不允许使用具有相同签名的方法,这会使编译器无法从声明的类中检测出确切的重写等效方法



两个方法或构造函数,M和N,如果它们 有,

  • 同名
  • 相同的类型参数(如果有)(),以及
  • 在使N的形式参数类型适应该类型之后 M的参数,形式参数类型相同
在一个类中声明两个具有重写等效签名的方法是编译时错误。


要实现重写,您正在违反重载规则

  • 不同方法的参数数量不同
  • 参数类型不同(如更改 是一个浮点到一个整数)
  • 因此,在您的情况下,不能让相同的方法名具有相同的方法参数(在您的情况下没有参数)和不同的返回类型


    如果将参数添加到某个接口方法中,则代码将编译

    interface ParentA {
        void display();
    }
    
    interface ParentB {
        int display(int x);
    }
    
    class Child implements ParentA, ParentB {
        @Override
        public void display() {
            System.err.println("Child ParentA");
        }
    
        @Override
        public int display(int x) {
            System.err.println("Child ParentB");
            return 0;
        }
    }
    

    如果您发现自己处于这种情况,并且无法以更简洁的方式解决,则可以使用一个或两个内部类将调用转发给新命名的方法:

    class Child {
        private class ParentAImp implements ParentA {
          @Override
          public void display() {
              displayParentA();
          }
        }
    
        private class ParentBImp implements ParentB {
          @Override
          public int display() {
              return displayParentB(); 
          }
        }
    
        public ParentA asParentA(){ return new ParentAImp(); }
        public ParentB asParentB(){ return new ParentBImp(); }
    
        private void displayParentA() {
            System.err.println("Child ParentA");
        }
    
        private int displayParentB() {
            System.err.println("Child ParentB");
            return 0;
        }
    }
    
    缺点是现在要从
    子接口
    到您必须执行的接口:

    ParentA parentA = child.asParentA();
    ParentB parentB = child.asParentB();
    

    如果您从Child实例上的一些代码调用方法的角度考虑:

    Child child = new Child();
    child.display();
    
    将调用哪个显示方法?考虑到它可能是任何一种方法,您都会看到编译时错误

    在Java8中解决这个问题的一个有趣方法是在其中一个接口中使用默认方法;这些都有自己的一套规则

    Jops的出色回答将为您提供指导。