我对这段代码非常困惑:
class A {}
class B extends A {}
public class ComingThru {
static String s = "-";
static void sifter(A[]... a2) {
s+="1";
}
static void sifter(B[]... b1) {
s+="2";
}
static void sifter(Object o) {
s+="4";
}
public static void main(String[] args) {
A[] aa = new A[2];
B[] ba = new B[2];
sifter(aa,ba);
System.out.println(s);
}
}
它输出为-1
,但是由于找不到匹配的函数,应该有编译错误。
答案 0 :(得分:2)
不,这不会给出编译错误。因为有一个完美的方法签名匹配调用,因为B也是A.这就是所谓的继承。如果再次检查代码,
class A {}
class B extends A {}
上面的代码使它能够编译和执行。
static void sifter(A[]... a2) {
s+="1";
}
上面的方法可以通过传递可变长度的A类数组或其子类型(即A的子类,即B)来调用
答案 1 :(得分:1)
匹配方法是static void sifter(A[]... a2)
,因为B扩展A.
这就是为什么你没有得到编译错误。
如果你看得更深(即编译/反编译),你会看到在编译的字节码中有以下内容。
static void sifter(A a[][]) {...}
static void sifter(B b[][]) {...}
static void sifter(Object o) {...}
public static void main(String args[])
{
A aa[] = new A[2];
B ba[] = new B[2];
sifter(new A[][] {
aa, ba
});
System.out.println(s);
}
然后它更清楚为什么它工作正常,以及为什么它调用它调用的方法。
答案 2 :(得分:1)
可替代性是面向对象编程的一个原则。它指出,在计算机程序中,如果S是T的子类型,则类型T的对象可以用类型S的对象替换(即,类型S的对象可以替换类型为T的对象。
因此,您可以将B作为A传递给A期望的方法并找到匹配项。
static void sifter(A[]... a2)
答案 3 :(得分:1)
找到匹配的方法
static void sifter(A[]... a2) { s+="1"; }
将调用此方法,因为A的层次结构较高,并且可以在其中捕获B的引用。
这就是输出为"-1"
答案 4 :(得分:0)
由于B扩展A,它将与此函数匹配
`static void sifter(A[]... a2) { s+="1"; }` //means any number of arrays of type A can be accepted and B is of type A.
如果删除它,您将收到编译错误。
答案 5 :(得分:0)
这可以帮助您理解您是否将此类重命名为此类。
class Fruit {}
class Apple extends Fruit {}
由于Apple是Fruit,因此调用需要Fruit数组的方法(static void sifter(Fruit[]... a2)
)