views:

198

answers:

4

I've learned all these programming terms in Swedish so please bear with me..

I'm having problems calling a method in a subclass which should override a method in the superclass.

Here is the class structure with removed code:

public interface Movable {
    public void move(double delta);
}
public abstract class Unit implements Movable, Viewable{
    public void move(double delta){
            System.out.println("1");
    }

}
public class Alien extends Unit{
    public void move(long delta){
     System.out.println("2");
    }
}
public class Player extends Unit{
    public void move(long delta){
     System.out.println("3");
    }
}


public void main(){
    ArrayList<Unit> units = new ArrayList<Unit>();
    Unit player = new Player();
    Unit alien = new Alien();
    units.add(player);
    units.add(alien);
    for (int i = 0; i < this.units.size(); i++) {
     Unit u = (Unit) this.units.get(i);
     u.move();
    }
}

This would output 1 and 1, but I want it to output 2 and 3.
What am I doing wrong? I thought this was how it worked.

+2  A: 

You need to add the @Override flag to the move function in your alien and player classes.

that would've helped you notice that you are not quite overriding your move since the type in alien/player are long, not doubles

yx
The annotation doesn't have any magic properties; it's just tells the compiler your intent. Overriding methods should work even if you don't include the annotation.
Outlaw Programmer
in this case it would've helped him catch his problem where he had long instead of double
yx
Yup, but the way you phrased your answer ("You need to...") makes it seem like you're suggesting just adding that keyword will somehow trigger the polymorphic call to work.
Outlaw Programmer
+10  A: 

Your subclasses (Alien and Player) aren't overriding the move() method in their parent class because you have declared 'delta' as a long and not a double.

You can have the compiler spot some of these errors by using the @Override annotation.

Outlaw Programmer
+1 for @Override.
Michael Myers
*seconds the +1 for @Override*
Daniel Bingham
+10  A: 
public class Alien extends Unit{
    public void move(long delta){
        System.out.println("2");
    }
}
public class Player extends Unit{
    public void move(long delta){
        System.out.println("3");
    }
}

Here's your problem, in the interface you have move declared as:

public void move(double delta)

But your child classes declare a:

public void move(long delta)

That creates a new function, separate from move and doesn't override it. To fix it change Alien's and Player's move functions to:

public void move(double delta)

Also, as Outlaw Programmer points out, you can have the compiler catch this sort of error by adding an @Override annotation right above the declaration of any function you intend to override a function in the parent class. Like so:

public class Alien extends Unit {
    @Override
    public void move(double delta) {
        System.out.println("2");
    }
}
Daniel Bingham
Doh >.< Thank you! :)
Baversjo
+2  A: 

Your child class does not implements the same method signature:

public void move(double delta);

is not the same as:

public void move(long delta);

To catch this kind of error at compile time, you can add @Override in the method signature. The compiler will check if the child class do in fact override a method in the parent class.

Thierry-Dimitri Roy