gpt4 book ai didi

java - java中的向下转型+调用带有可变参数的方法

转载 作者:行者123 更新时间:2023-12-03 02:48:32 25 4
gpt4 key购买 nike

当我调用 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 类的一个对象。并且 Faloodeh 类的 displayName(String...s) 不会被覆盖。仍在输出中,它显示 test Icecream为什么会这样?

最佳答案

这里的关键点是将 displayName(String... s) 更改为 displayName(String s) 会导致 displayName(String s) Faloodeh 中的 code> 方法来覆盖其父类(super class)中的方法。

Icecream.displayName(String... s)Faloodeh.displayName(String s) 具有不同的签名,因此它们不会相互覆盖。但是将前者更改为接受一个 String 只会导致它们具有相同的签名,从而导致发生覆盖。

在Java中,方法调用大致分三步解决(更多信息: JLS §15.12 ,我还详细解释了 here ):

  1. 找到类来搜索适用的方法。这基于您调用该方法的对象的编译时类型。在本例中,为aa 的编译时类型是 Icecream,因此仅考虑 Icecream 的方法。请注意,它在 Faloodeh 中找不到 displayName 方法,因为 a 的编译时类型是 Icecream
  2. 根据您传递的参数确定要调用的方法的哪个重载。这里只有一种选择。在更改之前和之后,displayName 是唯一与您传递的参数兼容的重载。
  3. 根据调用该方法的对象的运行时类型确定要调用该方法的哪个实现。 a 的运行时类型是 Faloodeh。更改之前,Faloodeh 中未覆盖 displayName,因此它调用父类(super class)实现。更改后,displayName 被覆盖,因此调用 Faloodeh 中的实现。

关于您的编辑:

在本例中,由于 b 的编译时类型为 Faloodeh,因此要搜索的类为 Faloodeh(步骤 1)。但是,有 2 种方法与您提供的参数相匹配(第 2 步):

  • displayName(String...),在 Faloodeh 中声明,并且;
  • displayName(String) 是继承的。

在这种情况下,编译器总是倾向于不带变量参数的重载 - displayName(String)。这在 JLS §15.12.2 中有明确规定。 。特别是,步骤2进一步分为三个子步骤。第一个子步骤尝试查找不允许可变数量方法的方法,如果任何子步骤找到任何方法,则跳过其余子步骤。

关于java - java中的向下转型+调用带有可变参数的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61044714/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com