Overriding varargs in java [duplicate]
Overriding varargs in java [duplicate]
This question already has an answer here:
I was trying to answer another SO question which led me to me asking my own one. I did some research but could not find any information on the above topic.
I have an abstract class Character
which has 1 abstract method defined below with varargs parameter
Character
public abstract class Character
public abstract void doSomething(int... values);
I was under the impression that any class that extends this class could override this method with any number of parameters.
// 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
But both the above examples resulted in a compile time error. I wanted to know what am I missing here? Is the above mentioned scenario even possible?
Any help is appreciated.
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
Because it can be called with any number of parameters right?
– Nicholas K
Aug 23 at 18:09
3 Answers
3
Variable argument functions in Java is a pure compiler trick: when you declare a method like this
public abstract void doSomething(int... values);
the compiler creates a method like this
public abstract void doSomething(int values);
and makes a "mental note" for itself to let you call doSomething
with any number of integer parameters as you wish. When you make a call, the compiler wraps the parameters that you list to an array, and passes that array to an implementation of doSomething
.
doSomething
doSomething
As for an ability to override such method with an implementation taking a fixed number of parameters, this would be impossible: if Java were to allow it (which it does not), programmers would be able to create class hierarchies that violate the interface of abstract classes that they extend. In your first case, Player
would not be able to handle this call:
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
would have the same problems, too.
NPC
You can override variable-argument method with a method taking an array:
@Override
void doSomething(int values)
...
Demo.
@NicholasK Absolutely - you can override it with
void doSomething(int values);
– dasblinkenlight
Aug 23 at 18:13
void doSomething(int values);
Fantastic answer. That cleared things up a lot, especially after you edited it! So its more like I need to override it using only an array of type int.
– Nicholas K
Aug 23 at 18:15
And also, It doesn't really help if I make the method abstract with
varargs
correct? Because in the end I'm not really achieving anything if finally it has to be overridden by an array of type int.– Nicholas K
Aug 23 at 18:21
varargs
@NicholasK Making it vararg in the abstract class is useful, because it lets the callers to invoke the method with variable number of arguments when calling through a variable typed as abstract class, i.e.
Character player = new Player()
instead of Player player = new Player()
.– dasblinkenlight
Aug 23 at 18:27
Character player = new Player()
Player player = new Player()
dasblinkenlight - sorry I didn't get that?
– Nicholas K
Aug 23 at 18:29
It is because you are overloading the method, not overriding. To override, you need to have the exact same parameters, here varargs -> int... or array -> int.
You can see the difference between both here : https://stackoverflow.com/a/2469860/8923905
I think you have the concept of abstract
methods all wrong. When a class subclasses an another abstract
class, it should provide a concrete implementation of the base class's abstract
methods.
abstract
abstract
abstract
Thus when you declare a method like:
abstract void doSomething(int someInt);
abstract void doSomething(int someInt);
The subclassing class, must provide a concrete implementation for a method with the same signature. Anything other than that is considered an invalid method declaration that results in the compilation error you're seeing.
I think you should better have a look at the documentation explaining the proper usage of abstract classes and methods.
https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html
The confusion here was not on abstract classes and interfaces. It was on an abstract method that has varargs parameters.
– Nicholas K
Aug 23 at 18:20
I was under the impression that any class that extends this class could override this method with any number of parameters Why?
– Sotirios Delimanolis
Aug 23 at 18:08