cha*_*_ma 7 java polymorphism inheritance
在下面的代码中
class A {
public void v(int... vals) {
System.out.println("Super");
}
}
class B extends A {
@Override
public void v(int[] vals) {
System.out.println("Sub");
}
}
Run Code Online (Sandbox Code Playgroud)
然后我可以称之为new B().v(1, 2, 3);//print Sub rather than Super
荒谬但确实运作良好.如果我换B
到
class B {
public void v(int[] vals) {
System.out.println("Not extending A");
}
}
Run Code Online (Sandbox Code Playgroud)
呼叫new B().v(1, 2, 3);
将无效.你必须称之为new B().v(new int[]{1, 2, 3});
,为什么?
在JDK 1.7,无论你的例子编译,我不相信他们应该.
很容易理解为什么第二个版本没有 - 当B
没有扩展时A
,根本没有varargs的指示,所以编译器没有理由将三个int
参数的参数列表转换为单个int[]
.更有趣的情况是B
不会延长A
.
编译器发现的签名v(int[] vals)
,其不使用可变参数.规范中没有任何内容可以说它应该查找继承链以查找其他声明之一(可能有多个声明)是否使用了varargs.它出现在您的JDK 1.6版本中这一事实表明这是一个编译器错误,此后一直被修复.(我刚刚复制了JDK 1.6.0_39中的错误.)
基本上,如果您希望能够以B.v()
varargs样式语法调用,B.v()
则应使用varargs声明.当然,如果你改变它以便编译时类型A
,那将是有效的:
A a = new B();
a.v(1, 2, 3);
Run Code Online (Sandbox Code Playgroud)
甚至(ick):
((A) new B()).v(1, 2, 3);
Run Code Online (Sandbox Code Playgroud)
请注意,如果您与您一起编译,-Xlint
则会收到警告B
:
Test.java:14: warning: v(int[]) in B overrides v(int...) in A; overriding method
is missing '...'
public void v(int[] vals) {
^
Run Code Online (Sandbox Code Playgroud)