gpt4 book ai didi

java - var-arg 方法中的方法重写

转载 作者:行者123 更新时间:2023-12-02 00:53:36 25 4
gpt4 key购买 nike

方法重写时出现意外输出 - var-arg 方法。父类有方法 m1(int...x) 和子类 m1(int[] x)

1 -- Child 中的 m1(int[] i) 是否会覆盖 Parent 中的 m1(int...x)

2 -- 为什么 p1.m1(3,10,9,0,5); 打印正常输出并且不会引发方法调用 p1 的编译器或运行时错误。 m1(3,10,9,0,5); 与 Child 类中的 m1(int[] i) 不匹配。

3 -- 我已将 int 值作为参数传递给 Child 类中的 m1(int[] i) 但它如何将其保存到一维 int 数组 i ??

class Parent {
public void m1(int... x) {
System.out.println("parent");
}
}

class Child extends Parent {
public void m1(int[] i) {
System.out.println("child");
System.out.println(i[0]);
System.out.println(i.length);
}

public void m1() {
System.out.println("child-0");
}
}

class Main {
public static void main(String[] args) {

Parent p = new Parent();
p.m1(10);

Child c = new Child();
c.m1();

Parent p1 = new Child();
p1.m1(3, 10, 9, 0, 5);

}
}

最佳答案

您问题的原始版本是这样问的:

First method call p1.m1(3,10,9,0,5); is it considered as method overriding or not?

方法调用不会覆盖。重写或不重写的是方法声明

事实上,Child 中的 m1(int[]) 确实会覆盖 Parent< 中的 m1(int...)/!请参阅我的答案末尾的 JLS 引用资料来解释原因。直观的解释是,可变参数是数组参数的语法糖,它允许调用者隐式创建数组。被调用方法在常规情况和等效 var args 情况下的行为相同。

那么为什么你的代码会编译、运行并给出你所看到的答案呢?

事情是这样的:

  1. p1 被声明为具有 Parent 类型。
  2. Parent 类声明 public void m1(int... x)
  3. 因此 p1.m1(3,10,9,0,5) 解析为允许 varags 的方法。
  4. 因此,代码编译为实际执行此操作的代码:

       p1.m1(new int[]{3,10,9,0,5})
  5. 在运行时,p1 的值实际上是 Child 的一个实例。因此,调用的方法是 Child 类中的 m1 重写。

<小时/>

1 -- m1(int[] i) in Child does it override m1(int...x) in Parent?

是的。

2 -- how come p1.m1(3,10,9,0,5); prints normal output and doesn't raise Compiler or Runtime error that method call p1.m1(3,10,9,0,5); doesn't match with m1(int[] i) in class Child.

参见上面的解释。

但请注意,如果您进行了更改:

Parent p1 = new Child();
p1.m1(3,10,9,0,5);

Child p1 = new Child();
c1.m1(3,10,9,0,5);

收到编译错误。

3 -- I have passed int values as an argument to m1(int[] i) in Child class but how is it able to save it to 1 dimensional int array i ??

参见上面的解释。 调用者从 vargs 参数隐式创建一个 int[]

<小时/>

JLS 8.4.1声明如下:

The declared type of a formal parameter depends on whether it is a variable arity parameter:

  • If the formal parameter is not a variable arity parameter, then the declared type is denoted by UnannType if no bracket pairs appear in UnannType and VariableDeclaratorId, and specified by §10.2 otherwise.

  • If the formal parameter is a variable arity parameter, then the declared type is an array type specified by §10.2.

JLS 8.4.8.1状态:

An instance method mC declared in or inherited by class C, overrides from C another method mA declared in class A, iff all of the following are true:

  • ...

  • The signature of mC is a subsignature (§8.4.2) of the signature of mA.

JLS 8.4.2状态:

Two methods or constructors, M and N, have the same signature if they have the same name, the same type parameters (if any) (§8.4.4), and, after adapting the formal parameter types of N to the the type parameters of M, the same formal parameter types.

The signature of a method m1 is a subsignature of the signature of a method m2 if either:

  • m2 has the same signature as m1, or

  • the signature of m1 is the same as the erasure (§4.6) of the signature of m2.

    Two method signatures m1 and m2 are override-equivalent iff either m1 is a subsignature of m2 or m2 is a subsignature of m1.

关于java - var-arg 方法中的方法重写,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57839392/

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