在 java 中覆盖可变参数
Overriding varargs in java
我试图回答另一个 SO 问题,这导致我问自己的问题。我做了一些研究,但找不到关于上述主题的任何信息。
我有一个抽象 class Character
,它有 1 个抽象方法,下面定义了可变参数
public abstract class Character {
public abstract void doSomething(int... values);
}
我的印象是任何扩展此 class 的 class 都可以使用任意数量的参数覆盖此方法。
// 1st example
public class Player extends Character {
@Override
public void doSomething(int x, int y) { // Two params - do something }
}
// 2nd example
public class NPC extends Character {
@Override
public void doSomething() { // No params - do something }
}
但是上面两个例子都导致了编译时错误。我想知道我在这里错过了什么?上述情况是否可能?
感谢任何帮助。
Java 中的可变参数函数是纯粹的编译器技巧:当您声明这样的方法时
public abstract void doSomething(int... values);
编译器创建了一个这样的方法
public abstract void doSomething(int[] values);
并为自己创建一个 "mental note",让您可以根据需要使用任意数量的整数参数调用 doSomething
。当您进行调用时,编译器会将您列出的参数包装到一个数组中,并将该数组传递给 doSomething
.
的实现
至于使用固定数量参数的实现来覆盖此类方法的能力,这是不可能的:如果 Java 允许(但不允许),程序员将能够创建 class 层次结构,违反它们扩展的抽象 classes 的接口。在您的第一种情况下,Player
将无法处理此调用:
Character player = new Player(); // Allowed
player.doSomething(1, 2, 3, 4, 5); // What happens to 3, 4, and 5?
player.doSomething(1); // What value do we pass for y?
NPC
也会遇到同样的问题
您可以使用采用数组的方法覆盖可变参数方法:
@Override
void doSomething(int[] values) {
...
}
这是因为你重载了方法,而不是覆盖。要覆盖,您需要具有完全相同的参数,这里是 varargs -> int... 或 array -> int[].
你可以在这里看到两者的区别:
我认为您对 abstract
方法的概念完全错误。当一个 class 子 class 是另一个 abstract
class 时,它应该提供基本 class 的 abstract
方法的具体实现。
因此,当您声明如下方法时:
abstract void doSomething(int someInt);
subclassing class 必须为具有相同签名的方法提供具体实现。除此以外的任何内容都被视为无效的方法声明,会导致您看到的编译错误。
我认为您最好看看解释抽象 classes 和方法的正确用法的文档。
https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html
我试图回答另一个 SO 问题,这导致我问自己的问题。我做了一些研究,但找不到关于上述主题的任何信息。
我有一个抽象 class Character
,它有 1 个抽象方法,下面定义了可变参数
public abstract class Character {
public abstract void doSomething(int... values);
}
我的印象是任何扩展此 class 的 class 都可以使用任意数量的参数覆盖此方法。
// 1st example
public class Player extends Character {
@Override
public void doSomething(int x, int y) { // Two params - do something }
}
// 2nd example
public class NPC extends Character {
@Override
public void doSomething() { // No params - do something }
}
但是上面两个例子都导致了编译时错误。我想知道我在这里错过了什么?上述情况是否可能?
感谢任何帮助。
Java 中的可变参数函数是纯粹的编译器技巧:当您声明这样的方法时
public abstract void doSomething(int... values);
编译器创建了一个这样的方法
public abstract void doSomething(int[] values);
并为自己创建一个 "mental note",让您可以根据需要使用任意数量的整数参数调用 doSomething
。当您进行调用时,编译器会将您列出的参数包装到一个数组中,并将该数组传递给 doSomething
.
至于使用固定数量参数的实现来覆盖此类方法的能力,这是不可能的:如果 Java 允许(但不允许),程序员将能够创建 class 层次结构,违反它们扩展的抽象 classes 的接口。在您的第一种情况下,Player
将无法处理此调用:
Character player = new Player(); // Allowed
player.doSomething(1, 2, 3, 4, 5); // What happens to 3, 4, and 5?
player.doSomething(1); // What value do we pass for y?
NPC
也会遇到同样的问题
您可以使用采用数组的方法覆盖可变参数方法:
@Override
void doSomething(int[] values) {
...
}
这是因为你重载了方法,而不是覆盖。要覆盖,您需要具有完全相同的参数,这里是 varargs -> int... 或 array -> int[].
你可以在这里看到两者的区别:
我认为您对 abstract
方法的概念完全错误。当一个 class 子 class 是另一个 abstract
class 时,它应该提供基本 class 的 abstract
方法的具体实现。
因此,当您声明如下方法时:
abstract void doSomething(int someInt);
subclassing class 必须为具有相同签名的方法提供具体实现。除此以外的任何内容都被视为无效的方法声明,会导致您看到的编译错误。
我认为您最好看看解释抽象 classes 和方法的正确用法的文档。
https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html