发布于2021-09-19 23:05 阅读(1091) 评论(0) 点赞(1) 收藏(2)
当我调用时a.displayName("Test")
,它调用 Icecream 类的方法。displayName(String...s)
方法接受可变参数。输出-
test Icecream
test Faloodeh
test Faloodeh: Faloodeh
test Faloodeh: Faloodeh
但是当我将方法更改为displayName(String s)
(我已经在代码中注释掉了该部分)时,它会调用 Faloodeh 类的方法。新输出-
test Faloodeh
test Faloodeh
test Faloodeh: Faloodeh
test Faloodeh: Faloodeh
我想知道为什么会这样。
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");
}
}
**编辑- ** 感谢您的回答。请帮我解决另一个疑问。我将代码更改为 -
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");
}
}
现在这给出了以下输出 -
test Icecream
test Icecream
test Faloodeh: Faloodeh
test Faloodeh: Faloodeh
正如你们所解释的,这里 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 进一步分为三个子步骤。第一个子步骤尝试在不允许可变元方法的情况下找到方法,如果任何子步骤找到任何方法,则跳过其余子步骤。
作者:黑洞官方问答小能手
链接:http://www.javaheidong.com/blog/article/290012/05d5ed6eaa2a3f90114e/
来源:java黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 java黑洞网 All Rights Reserved 版权所有,并保留所有权利。京ICP备18063182号-2
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!