Héritage et protected [Résolu]

krimog 1863 Messages postés lundi 28 novembre 2005Date d'inscription 14 février 2015 Dernière intervention - 26 août 2011 à 15:17 - Dernière réponse : krimog 1863 Messages postés lundi 28 novembre 2005Date d'inscription 14 février 2015 Dernière intervention
- 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é. -
Afficher la suite 

Votre réponse

6 réponses

Meilleure réponse
sebmafate 4947 Messages postés lundi 17 février 2003Date d'inscription 14 février 2014 Dernière intervention - 9 sept. 2011 à 15:25
3
Merci
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

Merci sebmafate 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 124 internautes ce mois-ci

Commenter la réponse de sebmafate
Meilleure réponse
krimog 1863 Messages postés lundi 28 novembre 2005Date d'inscription 14 février 2015 Dernière intervention - 23 mai 2012 à 14:03
3
Merci
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é. -

Merci krimog 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 124 internautes ce mois-ci

Commenter la réponse de krimog
Whismeril 11618 Messages postés mardi 11 mars 2003Date d'inscription 17 juin 2018 Dernière intervention - 26 août 2011 à 15:55
0
Merci
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
Commenter la réponse de Whismeril
krimog 1863 Messages postés lundi 28 novembre 2005Date d'inscription 14 février 2015 Dernière intervention - 26 août 2011 à 16:06
0
Merci
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é. -
Commenter la réponse de krimog
Whismeril 11618 Messages postés mardi 11 mars 2003Date d'inscription 17 juin 2018 Dernière intervention - 26 août 2011 à 16:34
0
Merci
Au temps pour moi.


Whismeril
Commenter la réponse de Whismeril
Whismeril 11618 Messages postés mardi 11 mars 2003Date d'inscription 17 juin 2018 Dernière intervention - 26 août 2011 à 16:59
0
Merci
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
Commenter la réponse de Whismeril

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.