2009-04-06 7 views
1

J'ai un problème avec la conception de classe.Problème de polymorphisme - champs virtuels? (C#)

J'ai classe de base pour mes objets de jeu. Pendant le dessin, je dois récupérer la position de l'objet. Malheureusement, l'objet est vu comme son type de base donc la position n'est pas récupérée de la classe dérivée mais de son parent. champ Définir comme virtuel fixerait mon problème, mais il est impossible :(Comment puis-je concevoir le schéma de classe pour éviter ce problème

exemple simple de ce qui se passe.?

class BaseClass { public Vector2 position = new Vector2(){X=0,Y=0}; } 
class Class:BaseClass { public new Vector2 position = new Vector2(){X=10,Y=10}; } 

BaseClass c = new Class(); 
// c.position.X is now 0 
+0

Pourquoi cachez-vous le champ de classe de base en premier lieu? –

Répondre

3

Vous pouvez retravailler cette option pour utiliser . propriétés virtuelles à la place des champs Cela gérer les choses correctement

Si les propriétés ne sont pas une possibilité pour une raison quelconque, vous pouvez également retravailler votre constructeur comme suit:.

class BaseClass 
{ 
    public Vector2 position = new Vector2(){X=0,Y=0}; 
} 

class Class:BaseClass 
{ 
    public Class() 
    { 
     this.position = new Vector2(){X=10,Y=10}; 
    } 
} 

Ce n'est pas exactement la même chose, puisque vous ne masquez pas le champ de la classe de base avec le vôtre, mais il l'initialisera correctement pour que vous puissiez l'utiliser comme votre exemple le suggère.

1
  • Le mot-clé new indique de masquer le symbole du même nom défini dans la classe de base.
  • public champs sont considérés comme une « odeur » en C#

Solution: propriétés d'utilisation et override la propriété dans la classe dérivée:

class BaseClass { 
    public virtual Vector2 Position { 
     get { return new Vector2(){X=0,Y=0}; } 
    } 
} 

class Class : BaseClass { 
    public override Vector2 Position { 
     get { return new Vector2(){X=10,Y=10}; } 
    } 
} 

Vous pouvez utiliser un champ de support pour stocker les instances de Vector2.

Alternativement, vous pouvez laisser la classe de base gérer la position et passer juste une valeur initiale:

class BaseClass { 
    private Vector2 _position; 
    public BaseClass() { 
     _position = new Vector2(){X=0,Y=0}; 
    } 
    protected BaseClass(Vector2 initialPosition) { 
     _position = initialPosition; 
    } 
    public Vector2 Position { 
     get { return _position; } 
     set { _position = value; } 
    } 
} 

class Class : BaseClass { 
    public Class() : base(new Vector2(){X=10,Y=10}) { 
    } 
} 
+0

Pourquoi considérez-vous les champs publics comme une «odeur»? – d347hm4n