我有一个类设置,看起来像这样:
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}
}
我很惊讶地发现这不会编译;如果找不到类型someMethod
和I
的合适方法I
,则会发出错误消息。我认为它会起作用,因为如果I
是A
,B
和C
的超类,那么它会起作用。为什么Java不允许这样做?是否有任何解决方法,例如将I
作为抽象类?
此外,这个模式是否有名称,所以我不必继续将其称为"这"?
答案 0 :(得分:4)
签名public static someMethod(A, A)
可以接受A
或更多派生类型的A
。同样地,(A,B)
等签名。
您需要一种接受(I,I)
的方法,以便使用您在上面概述的任何类A
,B
,C
来调用它。可替代性沿着继承链向下 - 您定义的形式参数必须是您希望具有的最不具体的类型,然后可以传入该类型的任何适当的继承者或实现者。
答案 1 :(得分:3)
在编译时,根据提供的参数的编译时类型(以及其他内容)选择方法。
此处,您的参数属于I
类型,但您的D
类未提供任何static
个方法,其中包含两个I
类型的参数。
答案 2 :(得分:2)
想象一下这种情况:
new D( new I() {}, new I() {} ).doSomething();
这是完全合法的,但参数肯定不适合您提供的任何实现。
编译器无法知道或强制I
仅由A
,B
或C
实施。
如果您发现自己处于这种状况,那通常表明设计不佳。解决方案是编写接口I
,使其与实现它的方法无关。
接口的目的(粗略地说)是定义通用功能。如果所有实施者之间的功能并不常见,则没有理由在那里设置接口。
答案 3 :(得分:1)
就名称而言,看起来您可能尝试使用多次发送。