代码之家  ›  专栏  ›  技术社区  ›  Nicholas K

重写java中的varargs[duplicate]

  •  1
  • Nicholas K  · 技术社区  · 7 年前

    我正试着回答另一个如此的问题,这导致我问我自己的一个。我做了一些研究,但找不到关于上述主题的任何信息。

    Character 下面定义了一个带有varargs参数的抽象方法

    public abstract class Character {
       public abstract void doSomething(int... values);
    }
    

    我的印象是,任何扩展这个类的类都可以用任意数量的参数重写这个方法。

    // 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 }
    }
    

    但以上两个例子都导致编译时错误。我想知道我错过了什么?上述情况是否可能?

    如有任何帮助,我们将不胜感激。

    3 回复  |  直到 7 年前
        1
  •  4
  •   Sergey Kalinichenko    7 年前

    Java中的变量参数函数是一个纯粹的编译器技巧:当您声明这样的方法时

    public abstract void doSomething(int... values);
    

    编译器创建这样的方法

    public abstract void doSomething(int[] values);
    

    给自己做个“心理记录”让你打电话 doSomething 任意数量的整数参数。当您进行调用时,编译器将您列出的参数包装到一个数组中,并将该数组传递给 剂量测定

    至于用一个带有固定数量参数的实现来重写这种方法的能力,这是不可能的:如果Java允许它(它不允许),程序员将能够创建违反它们所扩展的抽象类接口的类层次结构。在你的第一个案子里, 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) {
        ...
    }
    

    Demo.

        2
  •  2
  •   Emmanuel H    7 年前

    这是因为您正在重载方法,而不是重写。要重写,您需要具有完全相同的参数,这里是varargs->int。。。或数组->int[]。

    你可以在这里看到两者的区别: https://stackoverflow.com/a/2469860/8923905

        3
  •  -1
  •   akourt    7 年前

    abstract 方法都错了。当一个类派生另一个类时 摘要 类,它应该提供基类的 摘要 方法。

    因此,当您声明如下方法时:

    abstract void doSomething(int someInt);

    子类必须为具有相同签名的方法提供具体实现。除此之外的任何内容都被视为导致您看到的编译错误的无效方法声明。

    我认为您最好看看解释抽象类和方法的正确用法的文档。

    https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html