Héritage et protected [Résolu]

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

Votre réponse

6 réponses

Meilleure réponse
Messages postés
4947
Date d'inscription
lundi 17 février 2003
Dernière intervention
14 février 2014
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

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources a aidé 104 internautes ce mois-ci

Commenter la réponse de sebmafate
Messages postés
1863
Date d'inscription
lundi 28 novembre 2005
Dernière intervention
14 février 2015
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é. -

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources a aidé 104 internautes ce mois-ci

Commenter la réponse de krimog
Messages postés
12381
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
13 décembre 2018
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
Messages postés
1863
Date d'inscription
lundi 28 novembre 2005
Dernière intervention
14 février 2015
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
Messages postés
12381
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
13 décembre 2018
0
Merci
Au temps pour moi.


Whismeril
Commenter la réponse de Whismeril
Messages postés
12381
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
13 décembre 2018
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.