Muk*_*nka 2 java variadic-functions downcast
当我调用时a.displayName("Test"),它调用 Icecream 类的方法。displayName(String...s)方法接受可变参数。输出-
test Icecream
test Faloodeh
test Faloodeh: Faloodeh
test Faloodeh: Faloodeh
Run Code Online (Sandbox Code Playgroud)
但是当我将方法更改为displayName(String s)(我已经在代码中注释掉了该部分)时,它会调用 Faloodeh 类的方法。新输出-
test Faloodeh
test Faloodeh
test Faloodeh: Faloodeh
test Faloodeh: Faloodeh
Run Code Online (Sandbox Code Playgroud)
我想知道为什么会这样。
class Icecream{
public void displayName(String...s){
System.out.println(s[0]+" "+"Icecream");
}
/*public void displayName(String s){
System.out.println(s+" "+"Icecream");
}
*/
public void describe(String s) {
System.out.println(s+" "+"Icecream: Ice cream");
}
}
class Faloodeh extends Icecream {
public void displayName (String s){
System.out.println(s+" "+"Faloodeh ");
}
public void describe (String s) {
System.out.println(s+" "+"Faloodeh: Faloodeh");
}
}
class Test {
public static void main(String arg[]) {
Icecream a=new Faloodeh ();
Faloodeh b=( Faloodeh)a;
a.displayName("test");
b.displayName("test");
a.describe("test");
b.describe("test");
}
}
Run Code Online (Sandbox Code Playgroud)
**编辑- ** 感谢您的回答。请帮我解决另一个疑问。我将代码更改为 -
class Icecream{
public void displayName(String s){
System.out.println(s+" "+"Icecream");
}
/*public void displayName(String s){
System.out.println(s+" "+"Icecream");
}
*/
public void describe(String s) {
System.out.println(s+" "+"Icecream: Ice cream");
}
}
class Faloodeh extends Icecream {
public void displayName (String...s){
System.out.println(s+" "+"Faloodeh ");
}
public void describe (String s) {
System.out.println(s+" "+"Faloodeh: Faloodeh");
}
}
class Test {
public static void main(String arg[]) {
Icecream a=new Faloodeh ();
Faloodeh b=( Faloodeh)a;
a.displayName("test");
b.displayName("test");
a.describe("test");
b.describe("test");
}
}
Run Code Online (Sandbox Code Playgroud)
现在这给出了以下输出 -
test Icecream
test Icecream
test Faloodeh: Faloodeh
test Faloodeh: Faloodeh
Run Code Online (Sandbox Code Playgroud)
正如你们所解释的,这里 b 是 Faloodeh 类的对象。和displayName(String...s)Faloodeh 班级不会被覆盖。仍然在输出中,它显示test Icecream
为什么这样?
这里的关键点是,改变displayName(String... s)对displayName(String s)原因displayName(String s)的方法Faloodeh来覆盖其超类中的方法。
Icecream.displayName(String... s)并且Faloodeh.displayName(String s)具有不同的签名,因此它们不会相互覆盖。但是将前者更改为接受一个String只会导致它们具有相同的签名,从而导致覆盖发生。
在 Java 中,方法调用的解析大致分为三个步骤(有关更多信息:JLS §15.12,我还在此处进行了更详细的解释):
a。a的编译时类型是Icecream,因此只会Icecream考虑 的方法。请注意,它没有找到displayName方法,Faloodeh因为 的编译时类型a是Icecream。displayName是唯一与您传递的参数兼容的重载。a的运行时类型是Faloodeh. 在改变之前,displayName没有在 中被覆盖Faloodeh,所以它调用了超类的实现。更改后,displayName将被覆盖,因此Faloodeh调用in 的实现。关于您的编辑:
在这种情况下,由于编译时类型b是Faloodeh,要搜索的类是Faloodeh(步骤 1)。但是,有 2 种方法与您提供的参数匹配(步骤 2):
displayName(String...)在Faloodeh, and 中声明;displayName(String) 这是继承的。在这种情况下,编译器总是倾向于没有变量 arity -的重载displayName(String)。这在JLS §15.12.2 中有明确规定。特别是,步骤 2 进一步分为三个子步骤。第一个子步骤尝试在不允许可变元方法的情况下找到方法,如果任何子步骤找到任何方法,则跳过其余子步骤。
| 归档时间: |
|
| 查看次数: |
482 次 |
| 最近记录: |