繁体   English   中英

具有重载方法的接口未按预期运行

[英]Interface with overloading methods not behaving as expected

我有以下接口的实现:

    Object map(Object object);

    Entity map(Dto object);

    Dto map(Entity object);

当我调用map(new Dto())时,我希望方法Entity map(Dto object)被调用。 调用方法Object map(Object object)

在打字和超载的丛林中,我错过了什么?

您缺少的是 java 的工作原理。

方法的“身份”,即写在 class 文件中的东西,不仅仅是方法名称 它是方法名称它来自的“类型” 参数的擦除类型(但不是名称),以及返回类型。

那么,你的 3 map 方法在那里? 它们是不同的方法 它们完全不同,它们不是彼此的重载,它们与void foo() {}void bar() {}一样不同。

Java 确实具有动态调度和覆盖,但前提是签名对齐。

javac决定您正在调用哪个方法 id(记住,方法的 'id' 是名称参数类型返回类型)。 运行时( java )然后选择该方法 id 的最具体的覆盖来运行。

这是一些 java 代码来驱动要点:

class Parent {
  void foo(Object o) {
    System.out.println("Parent.foo(Object)");
  }

  void foo(String o) {
    System.out.println("Parent.foo(String)");
  }
}

class Child extends Parent {
  void foo(String o) {
    System.out.println("Child.foo(String)");
  }
}

class Main {
  public static void main(String[] args) {
    Parent a = new Child();
    a.foo("hello"); // prints 'Child.foo(String)'
    Object b = "hello";
    a.foo(b); // prints 'Parent.foo(Object)'
    a.foo((String) b); // prints 'Child.foo(String)'
  }
}

结果是您不能在动态调度的重载方法中使用“收紧”类型。 即你不能 go:“哦,我想覆盖map方法,但前提是参数是这个子类型。如果它不是这个子类型,我只希望它到 Z34D1F91FB2E514B8576ZFAB176 到父级。” 如果你想要这种行为,你必须重写该方法:

class Parent {
  Object map(Object object) {}
}

class Child {
  Object map(Object object) {
    if (object instanceof Dto dto) return childMap(dto);
    return super.map(object);
  }

  Object childMap(Dto dto) {
     // your code specifically for Dto goes here
  }
}

我强烈建议以不同的方式命名该自定义的基于子的方法以避免混淆。 @Override注释可用于防止错误。 如果您认为一个方法是一个覆盖,请始终对其进行注释(该方法不会使方法成为覆盖,如果不是,它只会导致编译器出错。它是编译器检查的文档)。

暂无
暂无

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

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