begin process at 2008 07 06 12:52:40
1 205 544 membres
121 nouveaux aujourd'hui
14 119 membres club

Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum.
Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

HÉRITAGE PUBLIC ET PRIVÉ


Information sur la source

Catégorie :Tutoriaux Niveau : Expert Date de création : 28/10/2002 Date de mise à jour : 28/10/2002 08:53:08 Vu : 3 135

Note :
10 / 10 - par 3 personnes
10,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (1)
Ajouter un commentaire et/ou une note

Description

Nous utilisons couramment l'héritage public à des fins de réutilisation
Pour éviter de définir une classe à partir de zéro, on dérive notre classe
d'une classe existante qui procure un bon point de départ.
avec l'héritage public, TOUTES les méthodes (et attributs) de la classe de base
tombent automatiquement dans notre interface (partie publique de la classe).
L'héritage privé est un moyen de contrôler les méthodes que nous désirons exposer.

Source

  • /* ceci est sensé représenter un héritage public et deux héritages privés
  • ----------
  • | A |
  • ----------
  • | + f1 |
  • | + f2 |
  • ----------
  • ^ ^ ^
  • <<public>> <<private>> <<private>>
  • / | \
  • ---------- ---------- ----------
  • | BPub | | BPriv | | B |
  • ---------- ---------- ----------
  • | + f1 | | - f1 | | + f1 |
  • | + f2 | | - f2 | | - f2 |
  • ---------- ---------- ----------
  • */
  • #include <iostream.h>
  • class A{ //A est la Classe de Base
  • public:
  • void f1(){cout << "A::f1\n";};
  • void f2(){cout << "A::f2\n";};
  • };
  • class BPub : public A //BPub la classe dérivée de manière publique
  • {};//ici, rien à faire pour que f1 et f2 soient utilisables par des clients d'objets BPub
  • class BPriv : private A //BPriv la classe dérivée de manière privée
  • {};//ici, f1 et f2 ne sont pas utilisables par des clients d'objets BPriv
  • / /bien sûr, les méthodes que l'on peut mettre dans la classe BPriv peuvent se servir de f1 et f2
  • // il y a donc quand même héritage
  • /* on voit que par défaut, aucune méthode n'est utilisable dans le 'main'
  • par l'objet de type BPriv : la solution est de redéfinir les méthodes
  • dont l'on souhaite garnir notre interface (ici f1)
  • on définira alors la classe B ainsi :
  • */
  • class B : private A
  • {public :
  • void f1(){cout << "B::f1 appelle "; A::f1();};
  • };
  • /*ceci permet l'utilisation de f1 avec une variable objet de type B,
  • alors que pour la même variable le compilateur bloque les appels à f2.
  • */
  • int main()
  • {
  • BPub pub;
  • pub.f1(); //OK
  • pub.f2(); //OK
  • BPriv priv;
  • // priv.f1(); //ici, erreur de compilation
  • //la méthode f1 est bien publique pour A, mais elle est devenue privée pour BPriv
  • B pubpriv;
  • pubpriv.f1();//ici possible d'appeler f1 (redevenue publique dans B)
  • //pubpriv.f2();//ici impossible d'appeler f2 (restée privée dans B)
  • return 0;
  • }
  • /* Application : le Design Pattern d'Adapteur
  • Pour cette partie, le prérequis est la connaissance des interfaces
  • (méthodes virtuelles pures)
  • Nous voyons que l'utilisateur de notre classe B ne voit que les méthodes
  • que nous voulons bien lui montrer. On peut en profiter pour renommer les
  • méthodes de A dans B
  • Par exemple, une classe mère de type Liste avec des méthodes f1 et f2
  • servant à inserer() et retirer() peuvent etre changée dans la classe
  • dérivée nommée Pile en empiler() et depiler() avec l'implémentation suivante :
  • void Pile::empiler(int i){Liste::inserer(1, i);}
  • int Pile::depiler(){Liste::retirer(1);}
  • On peut alors "Adapter" notre classe à un composant logiciel préexistant qui
  • appelle les méthodes présentées par une interface IPile (empiler et depiler)
  • il suffit ensuite de déclarer la classe comme implémentant IPile ainsi :
  • class Liste
  • {public:
  • void inserer(int position, int nombre);
  • int retirer(int position);
  • ...
  • };
  • class IPile
  • {
  • virtual void empiler(int nombre)=0;
  • virtual int depiler()=0;
  • };
  • class B : private Liste, public IPile
  • {public :
  • void empiler(int nombre){Liste::inserer(1, i);
  • int depiler(){Liste::retirer(1);}
  • ...
  • };
  • Remarquons que l'on peut aussi atteindre ce design avec une donnée membre privée et la simple délégation.
  • Attention à ne pas utiliser le polymorphisme avec cet héritage privé
  • car l'upcasting n'est plus implicite comme dans l'héritage public !
  • */
/* ceci est sensé représenter un héritage public et deux héritages privés
		        ----------
		        |   A     |
		        ----------
		        | + f1   |
		        | + f2   |
 		        ----------
	         ^	          ^		 ^
	<<public>>   <<private>>   <<private>>       
	       /	          |                       \       
	----------	     ----------	----------	
	|  BPub  |	     | BPriv  |	|   B     |
	 ----------	     ----------	----------
	| + f1    |	     | - f1   |	| + f1   |
	| + f2    |	     | - f2   |	| - f2    |
	----------	     ----------	----------
*/

#include <iostream.h>

class A{ //A est la Classe de Base
public: 
	void f1(){cout << "A::f1\n";};
	void f2(){cout << "A::f2\n";};
};

class BPub : public A //BPub la classe dérivée de manière publique
{};//ici, rien à faire pour que f1 et f2 soient utilisables par des clients d'objets BPub 

class BPriv : private A //BPriv la classe dérivée de manière privée
{};//ici, f1 et f2 ne sont pas utilisables par des clients d'objets BPriv 
/ /bien sûr, les méthodes que l'on peut mettre dans la classe BPriv peuvent se servir de f1 et f2
// il y a donc quand même héritage

/* on voit que par défaut, aucune méthode n'est utilisable dans le 'main'
   par l'objet de type BPriv : la solution est de redéfinir les méthodes
   dont l'on souhaite garnir notre interface (ici f1)

  on définira alors la classe B ainsi :
*/
class B : private A
{public : 
void f1(){cout << "B::f1 appelle "; A::f1();};
};

/*ceci permet l'utilisation de f1 avec une variable objet de type B,
  alors que pour la même variable le compilateur bloque les appels à f2.
*/

int main()
{
	BPub pub;
	pub.f1(); //OK
	pub.f2(); //OK

	BPriv priv;
//	priv.f1(); //ici, erreur de compilation 
	//la méthode f1 est bien publique pour A, mais elle est devenue privée pour BPriv

	B pubpriv;
	pubpriv.f1();//ici possible d'appeler f1 (redevenue publique dans B)
	//pubpriv.f2();//ici impossible d'appeler f2 (restée privée dans B)
	
	return 0;
}


/* Application : le Design Pattern d'Adapteur
Pour cette partie, le prérequis est la connaissance des interfaces
(méthodes virtuelles pures)

  Nous voyons que l'utilisateur de notre classe B ne voit que les méthodes
que nous voulons bien lui montrer. On peut en profiter pour renommer les
méthodes de A dans B
Par exemple, une classe mère de type Liste avec des méthodes f1 et f2
servant à inserer() et retirer() peuvent etre changée dans la classe
dérivée nommée Pile en empiler() et depiler() avec l'implémentation suivante :
void Pile::empiler(int i){Liste::inserer(1, i);}
int  Pile::depiler(){Liste::retirer(1);}
On peut alors "Adapter" notre classe à un composant logiciel préexistant qui
appelle les méthodes présentées par une interface IPile (empiler et depiler)
il suffit ensuite de déclarer la classe comme implémentant IPile ainsi :

class Liste
{public:
	void inserer(int position, int nombre);
	int  retirer(int position);
	...
};
class IPile
{
	virtual void empiler(int nombre)=0;
	virtual int  depiler()=0;
};
  class B : private Liste, public IPile
{public : 
	void empiler(int nombre){Liste::inserer(1, i);
	int  depiler(){Liste::retirer(1);}
	...
};

Remarquons que l'on peut aussi atteindre ce design avec une donnée membre privée et la simple délégation.
 
Attention à ne pas utiliser le polymorphisme avec cet héritage privé
car l'upcasting n'est plus implicite comme dans l'héritage public !
*/
  • signaler à un administrateur
    Commentaire de mmuller57 le 28/10/2002 11:36:32

    Excellent tutoriel, 10/10 !

Ajouter un commentaire

Pub



Appels d'offres

Plugin Dialer outlook
Budget : 2 000€
Travail graphique- ill...
Budget : 1 000€
creation de marque et ...
Budget : 1 000€

CalendriCode

Juillet 2008
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

VS Express FR Gratuit !

VS Express en français et 100% gratuit !

Boutique

Boutique de goodies CodeS-SourceS