一个java类中的多个接口-哪个用于方法调用?
如果我有一个实现两个接口的类,我将该类发送给一个重载方法,该方法接受任何一个接口;将调用该方法的哪个变体 换句话说,如果我有这样的东西:一个java类中的多个接口-哪个用于方法调用?,java,inheritance,Java,Inheritance,如果我有一个实现两个接口的类,我将该类发送给一个重载方法,该方法接受任何一个接口;将调用该方法的哪个变体 换句话说,如果我有这样的东西: interface A {} interface B {} class C implements A, B { } class D { public static void doThings(A thing){ System.out.println("handling A");} public static void doThings(B
interface A {}
interface B {}
class C implements A, B { }
class D
{
public static void doThings(A thing){ System.out.println("handling A");}
public static void doThings(B thing){ System.out.println("handling B");}
public static void main(String[] args) {
doThings(new C());
}
}
我将C类发送到D中的方法:
doThings(C);
应该调用哪个方法?Java标准是否涵盖了这一点?这会导致编译时错误。
“方法doThings对于类型D是不明确的”
这就是你的答案
interface AAA { }
interface BBB { }
class C implements AAA, BBB { }
public class D
{
public static void doThings(AAA thing){
}
public static void doThings(BBB thing){
}
public static void main(String[] args){
C x = new C();
D.doThings(x);
}
}
下面是确切的错误:
C:\Programs\eclipse\workspace\TEST\src>javac D.java
D.java:17: reference to doThings is ambiguous, both method doThings(AAA) in D and method doThings(BBB) in D match
D.doThings(x);
^
1 error
但是,请注意,如果将x定义为aaax=newc()代码>
或asbbbx=newc()代码>,然后它编译为OK。现在
x
参考的类型(AAA或BBB)使
此版本是明确的。
这是一个编译时错误
。甚至不是运行时,这是一个编译时错误
清楚地解释了这一点
一个类可以继承多个同名字段。这种情况本身不会导致编译时错误。但是,在类的主体中,任何试图通过其简单名称引用任何此类字段的尝试都将导致编译时错误,因为此类引用是不明确的。
这正是您试图执行的操作。您将得到一个编译器错误,因为多个方法匹配,即,两个
方法都做事情
JLS确实涵盖了这一点。它介绍了如何解析哪个方法适用于调用方法的表达式
否则,我们会说方法调用是不明确的,并且会发生编译时错误
这是在找到多个匹配的方法之后发生的,一个方法并不比另一个方法更“具体”,并且没有一个方法是抽象的,我同意那些说这将导致Java编译时错误的人的说法
需要注意的是,Java是一种静态类型的语言——这意味着:将调用哪些方法(在本例中)将在编译时确定
这个规则也有例外——例如,当反射调用方法时
因此,在这种情况下,当编译器试图确定将调用绑定到哪个方法时——它将被迫进入一个不明确的情况——导致编译时错误。它将给您一个编译时错误:“方法doThings(a)对于类型D是不明确的”
来解决这个问题,而不是打电话
doThings(新的C())代码>
你可以打电话
doThings((A)新的C())代码>
或
doThings((B)新的C())代码>
确实如此。当你尝试它时它做了什么?只有一个方法具有给定的签名。我稍微更新了你的代码。不要让我们试着运行它,看看Java会有什么反应。我想你会得到一个编译错误。我的意思是,在询问之前实际尝试了什么?我同意这张海报。。。这应该会导致编译错误,因为Java是静态类型的,这会导致歧义。我正要发布这个,+1。作为附加信息,如果我们想显式调用变量处理a
或B
,我们可以使用我们感兴趣的类型的引用,或者只使用类似于doThings((B)的大小写新C())代码>。