2009-11-04 4 views
2

J'ai appris tous ces termes de programmation en suédois alors s'il vous plaît garder avec moi ..Java problème Polymorphisme

Je vais avoir des problèmes appelant une méthode dans une sous-classe qui devrait remplacer une méthode dans la superclasse.

Voici la structure de classe avec le code enlevé:

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(); 
    } 
} 

Ce serait la sortie 1 et 1, mais je veux à la sortie 2 et 3.
Qu'est-ce que je fais mal ? Je pensais que c'était comme ça que ça fonctionnait.

Répondre

12
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"); 
    } 
} 

Voici votre problème, dans l'interface que vous avez mouvement déclaré:

public void move(double delta) 

Mais vos classes d'enfants Déclarez une:

public void move(long delta) 

Cela crée une nouvelle fonction, distincte de mouvement et ne le remplace pas. Pour corriger ce problème changer Alien et les fonctions de déplacement du joueur à:

public void move(double delta) 

En outre, comme le souligne Outlaw Programmer, vous pouvez avoir le cran de compilateur ce genre d'erreur en ajoutant une annotation @Override juste au-dessus de la déclaration d'une fonction intention de remplacer une fonction dans la classe parente. Comme si:

public class Alien extends Unit { 
    @Override 
    public void move(double delta) { 
     System.out.println("2"); 
    } 
} 
+0

Doh>. Baversjo

2

Vous devez ajouter l'indicateur @Override à la fonction de déplacement dans vos classes d'extraterrestres et de joueurs.

qui ont aidé vous remarquez que vous ne surchargez pas tout à fait votre déménagement puisque le type de joueur étranger/sont longues, pas se double

+0

L'annotation n'a aucune propriété magique; c'est juste de dire au compilateur votre intention. Les méthodes de remplacement doivent fonctionner même si vous n'incluez pas l'annotation. –

+0

dans ce cas il l'aurait aidé à attraper son problème où il avait longtemps au lieu de double –

+0

Yup, mais la façon dont vous avez formulé votre réponse ("Vous devez ...") donne l'impression que vous suggérez simplement d'ajouter ce mot-clé déclenchera en quelque sorte l'appel polymorphique au travail. –

12

Vos sous-classes (Alien et le joueur) ne surchargez pas le mouvement() méthode dans leur classe parent parce que vous avez déclaré «delta» comme un long et non un double.

Vous pouvez demander au compilateur de repérer certaines de ces erreurs en utilisant l'annotation @Override.

+1

+1 pour @Override. –

+0

* secondes le +1 pour @ Remplacer * –

2

Votre classe enfant n'implémente pas la même signature:

public void move(double delta); 

n'est pas la même chose que:

public void move(long delta); 

Pour attraper ce genre d'erreur au moment de la compilation , vous pouvez ajouter @Override dans la signature de la méthode. Le compilateur vérifiera si la classe enfant remplace effectivement une méthode dans la classe parente.