Pages: [1]   Bas de page
Imprimer
Auteur Fil de discussion: [Résolu/C#] Constante dans une classe  (Lu 2756 fois)
0 Membres et 1 Invité sur ce fil de discussion.
archipel Hors ligne
Full Member
***
Messages: 181


Voir le profil WWW
« 22 Mars 2011, 20:20:38 »

Bonjour,

j'ai une petite question concernant plus la POO en général que le developpement sur xbox360 mais au moins j'inaugure la section  Smiley


J'ai une classe monstre
Code: (csharp)
public abstract class Monstre {
     protected bool herbivore;
}

et des classes de monstres qui en dérivent
Code: (csharp)
public class Goblin :  Monstre{
    public Goblin(){
         herbivore=true;
     }
}

public class Troll :  Monstre{
    public Troll(){
        herbivore=false;
    }
}

Si je fais ca, ca marche, je peux savoir si le monstre est herbivore ou non. Mais comme ca ne dépend pas vraiment de l'instance mais plutot de la classe instanciée je pensais le mettre comme constante de classe mais je capte vraiment rien aux constantes en c# :s

comme solution j'ai ça mais c'est vraiment moche
Code: (csharp)
public abstract class Monstre {
   
     protected virtual bool Herbivore{
          get{return true;} //aucune importance vu qu'il ne sera jamais appelé
     }

}

public class Goblin :  Monstre{
    public Goblin(){
     
     }
     protected override bool Herbivore{
          get{return true;}
     }

}

public class Troll :  Monstre{
    public Troll(){
       
    }
     protected override bool Herbivore{
          get{return false;}
     }
}


Smiley
Journalisée

DevBlog --------------->  Aanaa
EvilTroopa Hors ligne
Administrateur
*****
Messages: 649


Voir le profil WWW
1010011010 the Number of the Beast

« Réponse #1 : 22 Mars 2011, 20:38:29 »

Je me rappelle pas bien comment on fait en C#, mais dans la logique je ferais plutôt un truc du genre :
Code:
enum{
HERBIVORE,
CARNIVORE,
OMNIVORE,
COPROPHAGE,
INSECTIVORE,
}_Alimentation;

abstract class Monstre{
public static _Alimentation Alimentation;

//Methodes abstract diverses
}

class Vache extends Monstre{
public static const _Alimentation Alimentation = HERBIVORE;
}

Je sais pas si la syntaxe est bonne, mais niveau raisonnement, je ferais comme ça ! Wink
Journalisée

A mushroom a day, keeps the koopas away.
t4ils Hors ligne
Branleur
Elite Member
**
Messages: 963


Voir le profil WWW
« Réponse #2 : 22 Mars 2011, 21:43:03 »

J'aurais plutôt vu un
Code:
public const Boolean HERBIVORE = true
en début de classe à coté des attributs publics et privés.

Smiley
Journalisée

Le codage amateur ? Parce que je le veux bien.
archipel Hors ligne
Full Member
***
Messages: 181


Voir le profil WWW
« Réponse #3 : 22 Mars 2011, 21:45:40 »

oui, je comprends le raisonnement mais je n'arrive pas à le retranscrire en conservant la possibilité de transtypage (? pas sûr de ce que je dis)

En fait je veux pouvoir écrire ça :
Code: (csharp)
Monstre v = new Vache();
Afficher(v.Alimentation);

Ce que je fais en général pour avoir un tel comportement, c'est déclarer en virtual dans la classe mere et override dans la classe fille. Sauf que les regles du jeu ne sont pas les memes avec des constantes, on n'a pas le droit de les déclarer virtual.

Aussi, comme un const est forcément statique c'est inaccessible dans une instance, on doit écrire Vache.Alimentation. Pour palier à ça, j'ai rajouté un getter la classe Monstre:
Code: (csharp)
abstract class Monstre{
public const _Alimentation Alimentation = _Alimentation.HERBIVORE; //obligé de lui affecter quelque chose

public _Alimentation recupererAlimentation{
get{return Alimentation;}
}
}

mais ce "recupererAlimentation" me renvoie toujours l'alimentation de la classe Monstre Sad


edit :
@tails : c'est ce que j'ai fais apres avoir lu le post d'eviltroopa
« Dernière édition: 22 Mars 2011, 21:50:08 par archipel » Journalisée

DevBlog --------------->  Aanaa
smealum Hors ligne
Administrateur
*****
Messages: 674


Voir le profil WWW
« Réponse #4 : 22 Mars 2011, 21:47:16 »

Je me rappelle pas bien comment on fait en C#, mais dans la logique je ferais plutôt un truc du genre :
Code:
enum{
HERBIVORE,
CARNIVORE,
OMNIVORE,
COPROPHAGE,
INSECTIVORE,
}_Alimentation;

abstract class Monstre{
public static _Alimentation Alimentation;

//Methodes abstract diverses
}

class Vache extends Monstre{
public static const _Alimentation Alimentation = HERBIVORE;
}

Je sais pas si la syntaxe est bonne, mais niveau raisonnement, je ferais comme ça ! Wink
Le truc c'est que je crois que c'est un problème de syntaxe qu'il a justement.  whistle
Journalisée

EvilTroopa Hors ligne
Administrateur
*****
Messages: 649


Voir le profil WWW
1010011010 the Number of the Beast

« Réponse #5 : 22 Mars 2011, 21:55:16 »

Pas seulement, son problème vient aussi de l'utilisation d'un constante.

Par définition une constante est constante... donc si elle est déclarée dans ta classe mère, tu ne devrais pas pouvoir la modifier dans les classes filles. D'où l'utilisation d'un enum et de différents types d'alimentation.
J'ai proposé ça pour que tu puisses à l'avenir ajouter de nouvelles alimentations et pas seulement dire si un monstre est herbivore ou pas.

Donc, dans mon bout de code, faudrait déjà virer le "const" qui fait chier, et mettre la variable en private.
Elle serait ensuite seulement lisible via un getter statique.

Reste que si tu modifies cette variable statique depuis une vache (elle peut puisqu'elle est hérite de cette classe), elle peut décider que toutes les vaches deviennent carnivores.
Je crois que c'est comme ça qu'il y a des drames à Raccoon City...
Journalisée

A mushroom a day, keeps the koopas away.
archipel Hors ligne
Full Member
***
Messages: 181


Voir le profil WWW
« Réponse #6 : 22 Mars 2011, 22:13:34 »

Par définition une constante est constante... donc si elle est déclarée dans ta classe mère, tu ne devrais pas pouvoir la modifier dans les classes filles. D'où l'utilisation d'un enum et de différents types d'alimentation.
J'ai proposé ça pour que tu puisses à l'avenir ajouter de nouvelles alimentations et pas seulement dire si un monstre est herbivore ou pas.
J'avais mis un bool pour simplifier le code  Grin


J'ai l'impression que ce n'est tout simplement pas possible en C# cf la reponse récupérée la qui correspond beaucoup à ce que je disais dans mon premier post :
Citation
It is actually possible to combine virtual and static for a method or a member by using the keyword new instead of virtual.

Here is an example:
class Car
{
    public static int TyreCount = 4;
    public virtual int GetTyreCount() { return TyreCount; }
}
class Tricar : Car
{
    public static new int TyreCount = 3;
    public override int GetTyreCount() { return TyreCount; }
}

...

Car[] cc = new Car[] { new Tricar(), new Car() };
int t0 = cc[0].GetTyreCount(); // t0 == 3
int t1 = cc[1].GetTyreCount(); // t1 == 4

Obviously the TyreCount value could have been set in the overridden GetTyreCount method, but this avoids duplicating the value. It is possible to get the value both from the class and the class instance.

Now can someone find a really intelligent usage of that feature?
C'est donc bien un probleme de syntaxe mais ca derniere question me laisse songeur, je pense que je vais rechercher un autre moyen de faire.


et merci:)SmileySmiley (je ne me doutais pas avoir autant de réponses et si vite)
Journalisée

DevBlog --------------->  Aanaa
EvilTroopa Hors ligne
Administrateur
*****
Messages: 649


Voir le profil WWW
1010011010 the Number of the Beast

« Réponse #7 : 22 Mars 2011, 22:17:26 »

Je vois pas pourquoi tu devrais chercher un autre moyen de faire, simplement parce que le gars se pose des questions Azn
Selon moi, tu as là la bonne solution !
Journalisée

A mushroom a day, keeps the koopas away.
archipel Hors ligne
Full Member
***
Messages: 181


Voir le profil WWW
« Réponse #8 : 23 Mars 2011, 07:44:56 »

ouais mais la syntaxe est lourde  Cry

j'aurai preferé pouvoir faire la meme chose mais sans mettre de getter dans les classes filles Smiley
du coup je vais voir si j'ai pas de meilleures idées
par exemple comme chaque monstre a un numero unique, je pourrai faire dans une autre classe
bool[] herbivores = new bool[nombredemonstre]
mais ce que j'aime pas trop en faisant ça, c'est que si je rajoute un monstre, il faut que je pense à rajouter une nouvelle ligne à ce tableau
Journalisée

DevBlog --------------->  Aanaa
EvilTroopa Hors ligne
Administrateur
*****
Messages: 649


Voir le profil WWW
1010011010 the Number of the Beast

« Réponse #9 : 23 Mars 2011, 19:19:45 »

Si tu surcharges pas la méthode getter, ça renverra la variable définie dans la classe mère ?
Journalisée

A mushroom a day, keeps the koopas away.
archipel Hors ligne
Full Member
***
Messages: 181


Voir le profil WWW
« Réponse #10 : 23 Mars 2011, 22:14:20 »

oui parce qu'on ne peut pas surcharger un champ statique (juste pour m'embeter  Sad)
Journalisée

DevBlog --------------->  Aanaa
PypeBros Hors ligne
Hero Member
*****
Messages: 724


Voir le profil WWW
Posez-vous les bonnes questions

« Réponse #11 : 24 Mars 2011, 11:03:19 »

Citation
... Mais comme ca ne dépend pas vraiment de l'instance mais plutot de la classe instanciée je pensais le mettre comme constante de classe
A mon avis, mauvaise idée. Si en effet tous les trolls sont carnivores, en revanche, chaque instance de Monstre a sa valeur propre. Du coup, c'est effectivement une propriété d'instance pour celui qui cherchera à traiter tous les Monstres de la même manière.

ou alors tu serais obligé d'utiliser quelque-chose comme
Code:
shrek.getClass().régime & HERBE
pour savoir si le monstre shrek est herbivore ou non.

Utiliser une méthode getRégime() virtuelle ... pourquoi pas, surtout si tu as déjà d'autres méthodes virtuelles. Mais ça dépend surtout si quelqu'un à l'extérieur de ta classe a besoin de connaître le régime de tes monstres.

Code:
public static new int ArmsCount = 3;
est complètement orthogonal. Ce n'est utile que si tu as la flemme de retenir dans les méthodes propres à ta classe (et ses sous-classes) que les Trolls ont 3 bras. En aucun cas ça ne t'aidera au niveau de Monstre à savoir le nombre de bras de Monstre shrek.

Code:
bool[] herbivores = new bool[nombredemonstre]
C'est plus ou moins pour éviter ce genre de constructions qu'on a inventé la POO.

Voilà. J'espère que ça t'aide à y voir plus clair.
Journalisée

archipel Hors ligne
Full Member
***
Messages: 181


Voir le profil WWW
« Réponse #12 : 24 Mars 2011, 11:46:54 »

Citation
... Mais comme ca ne dépend pas vraiment de l'instance mais plutot de la classe instanciée je pensais le mettre comme constante de classe
A mon avis, mauvaise idée. Si en effet tous les trolls sont carnivores, en revanche, chaque instance de Monstre a sa valeur propre. Du coup, c'est effectivement une propriété d'instance pour celui qui cherchera à traiter tous les Monstres de la même manière.

ou alors tu serais obligé d'utiliser quelque-chose comme
Code:
shrek.getClass().régime & HERBE
pour savoir si le monstre shrek est herbivore ou non.

Utiliser une méthode getRégime() virtuelle ... pourquoi pas, surtout si tu as déjà d'autres méthodes virtuelles. Mais ça dépend surtout si quelqu'un à l'extérieur de ta classe a besoin de connaître le régime de tes monstres.
oui mon but est que ça soit accessible en dehors de la classe.

J'avais pensé à ce truc de getClass & cie mais j'en suis pas hyperfan

Code:
public static new int ArmsCount = 3;
est complètement orthogonal. Ce n'est utile que si tu as la flemme de retenir dans les méthodes propres à ta classe (et ses sous-classes) que les Trolls ont 3 bras. En aucun cas ça ne t'aidera au niveau de Monstre à savoir le nombre de bras de Monstre shrek.

Code:
bool[] herbivores = new bool[nombredemonstre]
C'est plus ou moins pour éviter ce genre de constructions qu'on a inventé la POO.

Voilà. J'espère que ça t'aide à y voir plus clair.

Il y a aussi ma manie de donner des noms à toutes les constantes que j'utilise (ça clarifie pas mal le code je trouve) mais là n'est pas le problème.
Ok mon tableau de bool ne semble pas être une bonne idée


mais pour revenir à getclass, c'est un peu ce qu'il se passe implicitement quand on appelle une méthode virtuelle telle que monstre.getregime(), il va directement faire monstre.getclass.getregime.
En gros faire un truc comme ça ?
Code:
public class Monstre{
     public static bool herbivore;
     bool getHerbivore(){
          return getclass().herbivore;
     }
}

public class Troll{
     public static bool herbivore = true;
}

je pense que je vais utiliser la solution "moche" du premier post

je mets en résolu mais je suis toujours ouvert à discussion Smiley

PS: les trolls n'ont pas trois bras Wink
Journalisée

DevBlog --------------->  Aanaa
PypeBros Hors ligne
Hero Member
*****
Messages: 724


Voir le profil WWW
Posez-vous les bonnes questions

« Réponse #13 : 24 Mars 2011, 13:09:44 »

Code:
public class Monstre{
     public static bool herbivore;
     bool getHerbivore(){
          return getclass().herbivore;
     }
}

public class Troll{
     public static bool herbivore = true;
}
PS: les trolls n'ont pas trois bras Wink
Je ne suis pas un spécialiste du C#, mais je vérifierais scrupuleusement que ça fonctionne effectivement avant de m'en servir... et en tout cas, ça paraît franchement moins lisible que la méthode virtuelle.
Journalisée

archipel Hors ligne
Full Member
***
Messages: 181


Voir le profil WWW
« Réponse #14 : 24 Mars 2011, 13:56:07 »

Je ne suis pas un spécialiste du C#, mais je vérifierais scrupuleusement que ça fonctionne effectivement avant de m'en servir... et en tout cas, ça paraît franchement moins lisible que la méthode virtuelle.
ça marche pas ou je n'arrive pas à le faire marcher peu importe

je vais me contenter de méthodes virtuelles, en plus si je le met en abstract je risquerai pas d'oublier de redéfinir dans les classes filles

c'est cool Azn
Journalisée

DevBlog --------------->  Aanaa
Pages: [1]   Haut de page
Imprimer

Aller à: