Héritage et protected

Résolu
krimog Messages postés 1860 Date d'inscription lundi 28 novembre 2005 Statut Membre Dernière intervention 14 février 2015 - 26 août 2011 à 15:17
krimog Messages postés 1860 Date d'inscription lundi 28 novembre 2005 Statut Membre Dernière intervention 14 février 2015 - 23 mai 2012 à 14:03
Bonjour à tous

Ce message n'est qu'à moitié une question. Car il m'est facile de contourner le problème, mais j'avoue être extrêmement surpris.

class A
{
    protected string _monChamp;
    protected virtual void maMethode(A monObjet)
    {
        monObjet._monChamp = "Hello";
    }
}

class B : A
{
    protected override void maMethode(A monObjet)
    {
        monObjet._monChamp = "Salut";
    }
}


Ce code ne compile pas à la ligne : monObjet.champ = "Salut";
L'erreur est la suivante : Impossible d'accéder au membre protégé 'A.champ' par l'intermédiaire d'un qualificateur de type 'A' ; le qualificateur doit être de type 'B' (ou dérivé de celui-ci).

Je comprends bien l'erreur, mais je suis vachement étonné que c'en soit une. Pourquoi, dans ce cas précis, ne peut-on pas accéder à un champ protected alors qu'on se trouve dans une classe fille ?
De plus, ce "problème" est-il propre au .net ou est-il présent dans tous les langages orientés objets ?

Krimog : while (!(succeed = try())) ;
- Nous ne sommes pas des décodeurs ambulants. Le style SMS est prohibé. -
A voir également:

6 réponses

sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 37
9 sept. 2011 à 15:25
Hello,

Je pense que la solution se trouve dans ta question.

Le mot-clé protected permet de cacher un membre d'une classe aux autres classes tout en laissant accès aux classes dérivées.

Hors dans ton cas, tu essayes d'accéder à ton champs par l'intermédiaire d'une autre classe.
Je sais, c'est tordu car B hérite de A... mais ici, on accède à A par l'extérieur.


Sébastien FERRAND
Ingénieur Concepteur Senior
Microsoft Visual C# MVP 2004 - 2009
Blog Photo
3
krimog Messages postés 1860 Date d'inscription lundi 28 novembre 2005 Statut Membre Dernière intervention 14 février 2015 49
23 mai 2012 à 14:03
Bonjour à tous

Je reviens sur cette question que j'avais posée il y a un certain temps. Et en fait, je comprends mieux la réponse de Sebmafate.

L'objet fourni en paramètre est de type A, pas de type B. L'objet en lui-même n'a rien à voir avec B, la classe courante. C'est donc normal de ne pas pouvoir avoir accès aux membres protected.

On peut aussi voir les choses comme ça : pour faire simple, un membre protected se comporte comme un membre privé, présent dans une classe et dans ses classes dérivées.

class A
    {
        private int _pro;

        void methodeA(A obj)
        {
            
        }
    }

    class B : A
    {
        void methodeB(A obj)
        {class A
    {
        protected int _pro;

        void methodeA(A obj)
        {
            
        }
    }

    class B : A
    {
        void methodeB(A obj)
        {
            // obj._pro n'existe pas car on peut considérer _pro comme un membre privé de A  et qu'on est dans la classe B
            // (obj as B)._pro existe (si obj est bien une instance de B) car on peut considérer _pro comme un membre privé de B et qu'on est dans la classe B
        }
    }
        }
    }


Ça a un gros avantage : imaginons une classe C héritant aussi de A. Ça paraît normal de ne pas pouvoir accéder à une propriété protégée de C depuis B.

Krimog : while (!(succeed = try())) ;
- Nous ne sommes pas des décodeurs ambulants. Le style SMS est prohibé. -
3
Whismeril Messages postés 19021 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 16 avril 2024 656
26 août 2011 à 15:55
Bonjour,

    class B : A
    {
        public B()
        {
            this.maMethode(this);
            string toto = base._monChamp;
        }
            
        protected override void maMethode(A monObjet)
        {
            base._monChamp = "Salut";
        }
    }


Ceci fonctionne chez moi.
J'ai ajouté le constructeur pour voir si il n'y a pas d'erreur à l'execution.

Whismeril
0
krimog Messages postés 1860 Date d'inscription lundi 28 novembre 2005 Statut Membre Dernière intervention 14 février 2015 49
26 août 2011 à 16:06
Salut

Le problème est que je dois accéder au champ _monChamp de l'objet monObjet, pas de l'objet courant (pour lequel je n'ai pas de problème).

Krimog : while (!(succeed = try())) ;
- Nous ne sommes pas des décodeurs ambulants. Le style SMS est prohibé. -
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Whismeril Messages postés 19021 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 16 avril 2024 656
26 août 2011 à 16:34
Au temps pour moi.


Whismeril
0
Whismeril Messages postés 19021 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 16 avril 2024 656
26 août 2011 à 16:59
J'ai ceci a te proposer, bien que cela contourne le problème:

    class A
    {
        protected string _monChamp;
        protected virtual void maMethode(A monObjet)
        {
            monObjet._monChamp = "Hello";
        }
        protected virtual void maMethode(A monObjet, string Texte)
        {
            monObjet._monChamp = Texte;
        }
    }

    class B : A
    {
        public B()
        {
            A tutu = new A();
            this.maMethode(tutu);
        }
            
        protected override void maMethode(A monObjet)
        {
            base.maMethode(monObjet, "Salut");
        }

    }



Whismeril
0
Rejoignez-nous