Partage
  • Partager sur Facebook
  • Partager sur Twitter

Héritage & attributs

Sujet résolu
    23 mars 2011 à 8:56:01

    Bonjour.

    Je suis actuellement en train de suivre différents tutoriels pour apprendre la POO à l'aide du C#.
    Cependant, je but sur un problème au niveau de l'héritage.

    J'ai une classe abstraite "Personne" qui possède deux attributs privés : "_nom" & "_prenom"
    [J'ai bien fait les accesseurs et les mutateurs]

    J'ai aussi une classe "Homme" qui hérite de la classe "Personne" et qui possède un attribut privé : "_bierePrefere"
    [Avec un accesseur appelé GetBierePrefere]

    J'instancie de la manière suivante ma classe Homme :
    Personne monHomme1 = new Homme("Gorfing" , "Amoclyo" , "Foster");

    Le problème vient ensuite lorsque j'essaye de passer mon objet dans une autre classe.
    La ligne suivante : Console.WriteLine(homme.GetPrenom + " " + homme.GetNom + " aime la " + homme.GetBiereFavorite );
    Renvoie l'erreur : 'Abstraction.Personne' ne contient pas de définition pour 'GetBiereFavorite'
    [Get* étant les accesseurs]

    Le tuto que je suis en ce moment parle de "Convertir la variable"... Mais l'explication fournie reste obscure
    Vous pouvez y avoir accès ici vers les trois quart de la page, après l'intitulé "Rendre une classe abstraite"


    Merci d'avance pour votre aide
    • Partager sur Facebook
    • Partager sur Twitter
    Au même titre qu'une imprimante ou un scanner, le geek est un périphérique relié à l'ordinateur, via l'interface 2CS (Chaise-Clavier-Souris)
      23 mars 2011 à 12:16:20

      Salut,

      Citation

      J'instancie de la manière suivante ma classe Homme :
      Personne monHomme1 = new Homme("Gorfing" , "Amoclyo" , "Foster");



      Déjà il faudrait peut être que tu fasses appel à ton constructeur de base pour bien instancier ton objet homme :

      Homme monHomme1 = new Homme("Foster"): base("Gorfing" , "Amoclyo");
      


      Commence par là :)
      • Partager sur Facebook
      • Partager sur Twitter
        23 mars 2011 à 12:49:24

        Citation : VinSe

        Déjà il faudrait peut être que tu fasses appel à ton constructeur de base pour bien instancier ton objet homme :

        Homme monHomme1 = new Homme("Foster"): base("Gorfing" , "Amoclyo");
        


        Commence par là :)


        Oula... >_<
        VinSe, une relecture du chapitre sur les constructeurs s'impose ;)

        Le problème vient plutôt du fait que la référence monHomme1 créée par paulauchon est une référence de type Personne, pas de type Homme (même si elle désigne une instance de Homme). Une référence de type Personne ne permet d'accéder qu'aux membres communs à toutes les Personnes. Si tu voulais pouvoir accéder aux membres de la classe Homme, tu aurais dû créer une référence de type Homme:

        Homme monHomme1 = new Homme("Gorfing" , "Amoclyo" , "Foster");
        Console.WriteLine(homme.GetPrenom + " " + homme.GetNom + " aime la " + homme.GetBiereFavorite );
        

        Dans le tuto que tu cites, l'auteur fait un casting de monHomme1 en Homme pour pouvoir accéder aux membres de Homme, donc ça donnerait quelque chose comme ça:

        Personne monHomme1 = new Homme("Gorfing" , "Amoclyo" , "Foster");
        Console.WriteLine(homme.GetPrenom + " " + homme.GetNom + " aime la " + ((Homme)homme).GetBiereFavorite );
        

        Mais c'est une très mauvaise pratique, et le tuto ne l'indique pas assez clairement (j'ai déjà soulevé ce problème, on va y remédier). En effet :
        - soit l'auteur est sûr que son objet est un Homme, auquel cas il est inutile d'utiliser une référence de type Personne;
        - soit il n'est pas sûr que c'est un Homme, et le casting va planter si ce n'en est pas un.


        Une remarque au passage : en C# les accesseurs (propriétés) ne commencent pas par "Get":

        public abstract class Personne
        {
            private string _prenom;
        
            public Personne(string prenom)
            {
                _prenom = prenom;
            }
        
            public string Prenom
            {
                get { return _prenom; }
                set { _prenom = value; }
            }
        
            // ...
        }
        
        public class Homme : Personne
        {
            private string _biereFavorite;
        
            public Homme(string prenom, string biereFavorite)
                : base(prenom)
            {
                _biereFavorite = biereFavorite;
            }
        
            public string BiereFavorite
            {
                get { return _biereFavorite; }
                set { _biereFavorite = value; }
            }
        
            // ...
        }
        
        // ...
        Homme monHomme1 = new Homme("Gorfing" , "Foster");
        Console.WriteLine(homme.Prenom + " aime la " + homme.BiereFavorite);
        



        • Partager sur Facebook
        • Partager sur Twitter
          23 mars 2011 à 13:38:32

          En effet merci pour la rectification :p.
          • Partager sur Facebook
          • Partager sur Twitter
            23 mars 2011 à 14:07:44

            Citation : Orwell

            Une référence de type Personne ne permet d'accéder qu'aux membres communs à toutes les Personnes. Si tu voulais pouvoir accéder aux membres de la classe Homme, tu aurais dû créer une référence de type Homme:



            Effectivement, c'est l'alternative dont je me suis servi dans un premier temps.
            Étant donné que je ne savais pas si c'était une bonne solution donc j'ai voulu approfondir.
            Apparemment j'ai bien fait puisque c'est la technique qu'il faut utiliser.*

            Citation : Orwell

            Dans le tuto que tu cites, l'auteur fait un casting de monHomme1 en Homme pour pouvoir accéder aux membres de Homme, donc ça donnerait quelque chose comme ça:



            YES ! Effectivement ça fonctionne. Et je comprend mieux comment ça fonctionne du coup :)
            Merci beaucoup
            [Enfin je retiens que c'est pas top comme technique]

            Citation : Orwell

            Une remarque au passage : en C# les accesseurs (propriétés) ne commencent pas par "Get":"



            Je retiens ce règle de formalisme ;)
            Merci pour ce petit bonus !
            • Partager sur Facebook
            • Partager sur Twitter
            Au même titre qu'une imprimante ou un scanner, le geek est un périphérique relié à l'ordinateur, via l'interface 2CS (Chaise-Clavier-Souris)

            Héritage & attributs

            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
            • Editeur
            • Markdown