Héritage et protected [Résolu]

Signaler
Messages postés
1860
Date d'inscription
lundi 28 novembre 2005
Statut
Modérateur
Dernière intervention
14 février 2015
-
Messages postés
1860
Date d'inscription
lundi 28 novembre 2005
Statut
Modérateur
Dernière intervention
14 février 2015
-
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

Messages postés
4936
Date d'inscription
lundi 17 février 2003
Statut
Modérateur
Dernière intervention
14 février 2014
36
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
Messages postés
1860
Date d'inscription
lundi 28 novembre 2005
Statut
Modérateur
Dernière intervention
14 février 2015
44
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é. -
Messages postés
15940
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
15 mai 2021
545
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
Messages postés
1860
Date d'inscription
lundi 28 novembre 2005
Statut
Modérateur
Dernière intervention
14 février 2015
44
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é. -
Messages postés
15940
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
15 mai 2021
545
Au temps pour moi.


Whismeril
Messages postés
15940
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
15 mai 2021
545
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