为什么输入类型是接口,参数类型是实现类,为什么Java找不到合适的方法?
Why can't Java find a suitable method when the input types are interfaces and the parameter types are implementing classes?
我有一个看起来像这样的 class 设置:
interface I{}
class A implements I{}
class B implements I{}
class C implements I{}
class D{
I a;
I b;
public D(I a, I b){
this.a = a;
this.b = b;
}
public void doSomething(){
D.someMethod(a, b);
}
public static someMethod(A, A){//do something}
public static someMethod(A, B){//do something}
public static someMethod(A, C){//do something}
public static someMethod(B, B){//do something}
public static someMethod(B, C){//do something}
}
我真的很惊讶地发现这不能编译;它会抛出一个错误,指出它无法为类型 I
和 I
找到合适的方法 someMethod
。我认为它会起作用,因为如果 I
是 A
、B
和 C
的超级 class,它就会起作用。为什么 Java 不允许这样做?是否有任何解决方法,例如将 I
设为摘要 class?
此外,是否有此模式的名称以便我不必一直将其称为 "this"?
在编译时,方法是根据提供的参数的编译时类型(除其他事项外)选择的。
在这里,您的参数是 I
类型,但是您的 D
class 没有提供任何具有两个 I
类型参数的 static
方法.
想象一下这个场景:
new D( new I() {}, new I() {} ).doSomething();
这是完全合法的,但参数肯定不适合您提供的任何实现。
编译器无法知道或强制执行 I
只会由 A
、B
或 C
实现。
如果您发现自己处于这种情况,这通常表明设计不佳。解决方案是编写接口 I
的方式与实现它的方法无关。
接口的目的(粗略地说)是定义通用功能。如果所有实现者之间的功能不通用,则没有理由在那里有一个接口。
签名 public static someMethod(A, A)
可以接受 A
或 A
的更多派生类型。同样,(A,B)
等签名。
您需要一个接受 (I,I)
的方法,以便使用您使用的任何 类 A
、B
、C
调用它上面勾勒出来。可替代性沿着继承链向下延伸——您定义的形式参数必须是您希望共有的最不具体的类型,然后可以传入该类型的任何适当的继承者或实现者。
顾名思义,您可能正在尝试使用多重分派。
我有一个看起来像这样的 class 设置:
interface I{}
class A implements I{}
class B implements I{}
class C implements I{}
class D{
I a;
I b;
public D(I a, I b){
this.a = a;
this.b = b;
}
public void doSomething(){
D.someMethod(a, b);
}
public static someMethod(A, A){//do something}
public static someMethod(A, B){//do something}
public static someMethod(A, C){//do something}
public static someMethod(B, B){//do something}
public static someMethod(B, C){//do something}
}
我真的很惊讶地发现这不能编译;它会抛出一个错误,指出它无法为类型 I
和 I
找到合适的方法 someMethod
。我认为它会起作用,因为如果 I
是 A
、B
和 C
的超级 class,它就会起作用。为什么 Java 不允许这样做?是否有任何解决方法,例如将 I
设为摘要 class?
此外,是否有此模式的名称以便我不必一直将其称为 "this"?
在编译时,方法是根据提供的参数的编译时类型(除其他事项外)选择的。
在这里,您的参数是 I
类型,但是您的 D
class 没有提供任何具有两个 I
类型参数的 static
方法.
想象一下这个场景:
new D( new I() {}, new I() {} ).doSomething();
这是完全合法的,但参数肯定不适合您提供的任何实现。
编译器无法知道或强制执行 I
只会由 A
、B
或 C
实现。
如果您发现自己处于这种情况,这通常表明设计不佳。解决方案是编写接口 I
的方式与实现它的方法无关。
接口的目的(粗略地说)是定义通用功能。如果所有实现者之间的功能不通用,则没有理由在那里有一个接口。
签名 public static someMethod(A, A)
可以接受 A
或 A
的更多派生类型。同样,(A,B)
等签名。
您需要一个接受 (I,I)
的方法,以便使用您使用的任何 类 A
、B
、C
调用它上面勾勒出来。可替代性沿着继承链向下延伸——您定义的形式参数必须是您希望共有的最不具体的类型,然后可以传入该类型的任何适当的继承者或实现者。
顾名思义,您可能正在尝试使用多重分派。