[英]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.