Programmation en C++ Héritage

Slides:



Advertisements
Présentations similaires
Spécialisation/généralisation Héritage Polymorphisme
Advertisements

1 Quelques précisions sur l'héritage. 2 Signification de super.f() appel à la méthode f() masquée super : désigne l'objet appelant comme s'il était de.
Tarak Chaari, Stéphane Frénot, Frédérique Laforest, Frédéric Le-Mouël JAV1 JAV – TD 5 Lhéritage en Java.
Leçon 3 : Héritage IUP 2 Génie Informatique
Introduction à la POO: Les classes vs les objets
Chapitre III Héritage (début)
COURS DE PROGRAMMATION ORIENTEE OBJET :
Classes abstraites et Interfaces
Introduction au paradigme orienté-objet (suite)
1 IFT 6800 Atelier en Technologies dinformation Le langage de programmation Java chapitre 3 : Classes et Objects.
Héritage Lhéritage permet de spécialiser une classe en définissant une relation de type « est une sorte de ». #include comptebancaire.h class CompteEpargne.
99 Réutilisation du code grâce à l'héritage. 9-2 Objectifs À la fin de ce cours, vous serez capables de : Définir l'héritage Utiliser l'héritage pour.
Héritage Licence Informatique Besançon Méthode et Outils pour la Programmation Françoise Greffier.
Héritage et composition
LIFI-Java 2004 Séance du Mercredi 22 sept. Cours 3.
La notion de type revisitée en POO
11/04/ L'héritage Cours 7 Cours 7.
Programmation objet La base.
12/04/ Le polymorphisme Cours 8 Cours 8.
Les classes et les objets Les données finales class A { … private final int n = 20 ; // la valeur de n est définie dans sa déclaration … } class A { public.
Cours du 5 novembre.
Les classes Introduction aux Langages Orientés Objets
Cours 4 (14 octobre) Héritage. Chapitre III Héritage.
Introduction à la programmation objet avec java
Héritage Conception par Objet et programmation Java
Exception Handling "Unfortunately, it's almost accepted practice to ignore error conditions, as if we're in a state of denial about errors." Bruce Eckel.
1 Après 3 séances ● Utilisation du système Linux – Il faut maîtriser l'utilisation de la souris (« copy/paste » des textes donnés) – Utilisation de la.
C++ Les fonctions. Présentation Utilité : Dès qu'un programme dépasse la centaine de lignes de code, il est pratique de pouvoir le décomposer en plusieurs.
Les systèmes d'information 1- Une pratique quotidienne 2- Les données 3- Approche conceptuelle 4- Notion de serveur 5- Conception d'un système d'information.
1 Après 5 séances ● Utilisation du système Linux – Il faut maîtriser l'utilisation de la souris (« copy/paste » des textes donnés) – Utilisation de la.
1 ● Conception ● Exemple de classes ● Fonctions virtuelles ● Fonctions virtuelles pures ● Classes abstraites Programmation en C++ Héritage.
1 Programmation en C++ IO en C++/SL. 2 Sortie à l’écran Exemple: #include int main () { std::cout
1 Programmation Orientée Objet ● Qu'est-ce qu'un objet ● Collaboration des objets ● Les classes ● Relations entre les classes – “Utilise”, “Contient”,
Stéphane Frénot, Frederique Laforest, Frédéric Le-Mouël IJA 1 TD 6 IJA Structures de données JAVA.
1 Programmation en C++ Fonctions ● Déclaration et définition de fonctions ● Arguments ● Surcharge ● Arguments optionnels ● Fonctions constantes ● Fonctions.
1 Programmation en C++ C++ de base ● Programme C++ ● Variables, objets, types ● Fonctions ● Namespace ● Tests ● Boucles ● Pointeurs, références.
1 Programmation en C++ C++ de base ● Programme C++ ● Variables, objets, types ● Types et opérations fondamentales ● Tests ● Boucles ● Pointeurs, références.
1 Programmation en C++ Cycle de vie ● La vie d'un objet ● Destructeur ● Gestion de mémoire dynamique.
1 Programmation en C++ IO en C++/SL ● Standard Library ● Types, objets pour IO ● L'entrée de clavier ● Sortie à l'écran ● Fichiers.
Programmation en C++ Standard Library
Modèle objet : les classes
java : l'héritage (rappel)
Pas de variable globale
Les notions de classe et d'objet
Programmation en C++ IO en C++/SL
Principes de programmation (suite)
Semaine 11 Les pointeurs (suite)
Les fonctions.
Les bases de données et le modèle relationnel
Programmation en C++ Fonctions
Langages de programmation TP10
Les interfaces en PHP.
Programmation en C++ IO en C++/SL
Programmation en C++ Classes
Programmation en C++ Fonctions
Programmation en C++ C++ de base
Modélisation avec UML 2.0 Partie II Diagramme de classes.
Programmation Orientée Objet C# El Akel Bouchra ISMONTIC Tanger 2013/2014.
Programmation Orientée Objet
Les classes et les objets
5. Les modules Découpage d’une application en modules
Les exceptions Le mécanisme des exceptions est destiné à permettre aux fonctions profondes d'une bibliothèque de notifier la survenue d'une erreur aux.
PRESENTATION ACCESS Editeur : Microsoft Environnement Windows (SE)
Principes de programmation (suite)
INTERFACE ET POLYMORPHISME
STREAMS (et fichiers).
Variables et accès en Java
Retour sur les interfaces
Transcription de la présentation:

Programmation en C++ Héritage Conception Exemple de classes Fonctions virtuelles Fonctions virtuelles pures Classes abstraites

Rappel: Relations entre les classes « Hérite » La relation « Hérite » (“Inheritance“) Une classe (A) peut hériter de l'état (des variables) et du comportement (des méthodes) d'une autre classe (B) On dit que la classe A représente un super-type (super-classe) de la classe B, représentant un sous-type (sous-classe) Ou que la classe A représente une généralisation de la classe B, représentant une spécialisation de la classe A Ou que la classe A représente une classe de base de la classe B, représentant une classe dérivée de la classe A Par exemple un vélo de montagne, un vélo de route ou un vélo tandem sont tous du type vélo Vélo Vélo de montagne Vélo de route Vélo tandem

Exemple Pour démontrer la conception et l'implantation de l'héritage nous allons développer des classes qui décrivent les animaux de compagnie dans une famille française habituelle Essayons de trouver des caractéristiques communes pour nos animaux typiques – le chat et le chien Chacun a son nom Il faut qu'on leur donne à manger – ils mangent Il nous parlent – le chien aboie, le chat miaule Les comportements spécifiques: Le chat chasse les souris Le chien monte la garde de la maison

La conception ... Chien nom Mange() Parle() MonteLaGarde() Chat nom Mange() Parle() ChasseSouris() ADC nom Mange() Parle() Les données membres et les fonctions communes peuvent être extraites dans une super-classe (ou classe de base) ADC (= Animal de compagnie)

... La conception ADC nom Mange() Parle() Chien Chat MonteLaGarde() ChasseSouris()

Les Classes (définition) #include <string> class ADC { public: ADC(std::string nom); void Mange(); void Parle(); std::string Nom(); private: std::string m_nom; }; #include “ADC.h” #include <string>  class Chien : public ADC { public: Chien(std::string nom); void MonteLaGarde(); }; La déclaration de la relation de l'héritage #include “ADC.h” #include <string>  class Chat : public ADC { public: Chat(std::string nom); void ChasseSouris(); }; ADC nom Mange() Parle() Chien MonteLaGarde() Chat ChasseSouris()

Les Classes (implantation) #include "ADC.h" #include <iostream> ADC::ADC(std::string nom) : m_nom(nom) { } void ADC::Mange() { std::cout << m_nom << " mange" << std::endl; void ADC::Parle() { std::cout << m_nom << " parle" << std::endl; std::string ADC::Nom() { return m_nom; #include "Chien.h" #include <iostream> Chien::Chien(std::string nom) : ADC(nom) { } void Chien::MonteLaGarde() { std::cout << Nom() << " monte la garde " << std::endl; #include "Chat.h" #include <iostream> Chat::Chat(std::string nom) : ADC(nom) { } void Chat::ChasseSouris() { std::cout << Nom() << " chasse la souris " << std::endl; ADC nom Mange() Parle() Chien MonteLaGarde() Chat ChasseSouris() Initialisation de la classe de base (super-classe)

Les Classes (utilisation) ... #include "Chien.h" #include "Chat.h" int main() { Chien chien("Bella"); Chat chat("Minette"); // Quand on arrive a la maison les ADCs nous font // la fête chien.Parle(); chat.Parle(); // Il faut leur donner à manger chien.Mange(); chat.Mange(); // Et tout le monde s'occupe de son travail chien.MonteLaGarde(); chat.ChasseSouris(); } main.cxx Déclaration des objets avec leurs types spécifiques (par des sous-classes) Appel de fonctions définies dans la classe de base Appel de fonctions définies dans les sous-classes [localhost]> ./chezNous Bella parle Minette parle Bella mange Minette mange Bella monte la garde Minette chasse une souris

... Les Classes (utilisation) #include "Chien.h" #include "Chat.h" int main() { Chien chien("Bella"); Chat chat("Minette"); ADC& adc1 = chien; ADC& adc2 = chat // Quand on arrive a la maison les ADCs nous font // la fête adc1.Parle(); adc2.Parle(); // Il faut leur donner à manger adc1.Mange(); adc2.Mange(); // Et tout le monde s'occupe de son travail chien.MonteLaGarde(); chat.ChasseSouris(); } main2.cxx Déclaration des objets avec le type générique (par la super-classe) Appel de fonctions définies dans la classe de base Appel de fonctions définies dans les sous-classes [localhost]> ./chezNous2 Bella parle Minette parle Bella mange Minette mange Bella monte la garde Minette chasse une souris

Après 1. étape La classe de base (ADC) implante la donnée membre commune Les sous-classes (Chien, Chat) héritent l'état implante des méthodes communes Les sous-classe (Chien, Chat) héritent de l'implantation des méthodes L'introduction de la classe de base nous a évité la duplication du code commun aux sous-classes

Spécialisation de fonctions ... Nous allons préciser notre modèle: Le chien mange des croquettes ProPlan Le chat mange des boites Whiskas Le chien aboie Le chat miaule Modélisation: ADC nom Mange() Parle() Chaque sous-classe redéfinit des fonctions de la classe de base Chien Mange() Parle() MonteLaGarde() Chat Mange() Parle() ChasseSouris()

... Spécialisation de fonctions ... Nous allons ajouter ces méthodes à des classes Chien, Chat: ADC nom Mange() Parle() #include “ADC.h” #include <string>  class Chien : public ADC { public: Chien(std::string nom); void Mange(); void Parle(); void MonteLaGarde(); }; #include “ADC.h” #include <string>  class Chat : public ADC { public: Chat(std::string nom); void Mange(); void Parle(); void ChasseSouri(); }; Chien Mange() Parle() MonteLaGarde() Chat Mange() Parle() ChasseSouris() Chien::Mange() { std::cout << nom() << " mange des croquettes ProPlan " << std::endl; } void Chien::Parle() { std::cout << Nom() << ": wouaf, wouaf !! " << std::endl; Chat::Mange() { std::cout << nom() << " mange des boites Whiskas " << std::endl; } void Chat::Parle() { std::cout << Nom() << ": miaou, miaou !! " << std::endl; La déclaration de la relation de héritage

... Spécialisation de fonctions On compile et exécute les deux programmes: [localhost] > ./chezNous Bella: wouaf, wouaf !!! Minette: miaou, miaou !!! Bella mange des croquettes ProPlan Minette mange des boites Whiskas Bella monte la garde Minette chasse une souris Si déclaration des objets avec leur types spécifiques (par des sous-classes) OK [localhost]> ./chezNous2 Bella parle Minette parle Bella mange Minette mange Bella monte la garde Minette chasse une souri Si déclaration des objets avec le type générique (par la super-classe) FAUX !!! ou plutôt ce n'est pas ce que nous voulions obtenir ...

Fonctions virtuelles ... Pour que la « bonne » fonction soit appelée il faut la déclarer virtual La « bonne » fonction = la fonction définie pour la classe dont le type dynamique de notre objet est L'objet défini par la référence adc1 est du type Chien, adc2 du type Chat La fonction virtuelle agit comme une interface pour les fonctions définies dans la classe de base et dans toutes les classes dérivées #include <string> class ADC { public: ADC(std::string nom); virtual void Mange(); virtual void Parle(); private: std::string m_nom; }; #include “ADC.h” #include <string>  class Chien : public ADC { public: Chien(std::string nom); virtual void Mange(); virtual void Parle(); void MonteLaGarde(); }; #include “ADC.h” #include <string>  class Chat : public ADC { public: Chat(std::string nom); virtual void Mange(); virtual void Parle(); void ChasseSouri(); }; Fonction déclarée virtuelle Il n'est pas obligatoire de re-déclarer les fonctions virtuelles dans des classes dérivées mais c'est une bonne pratique de le faire La déclaration de la relation de héritage

... Fonctions virtuelles On compile et exécute les deux programmes de nouveau: [localhost] > ./chezNous Bella: wouaf, wouaf !!! Minette: miaou, miaou !!! Bella mange des croquettes ProPlan Minette mange des boites Whiskas Bella monte la garde Minette chasse une souris Si déclaration des objets avec leur types spécifiques (par des sous-classes) OK [localhost]> ./chezNous2 Bella: wouaf, wouaf !!! Minette: miaou, miaou !!! Bella mange des croquettes ProPlan Minette mange des boites Whiskas Bella monte la garde Minette chasse une souris Si déclaration des objets avec le type générique (par la super-classe) OK

Les Classes (utilisation) main3.cxx L'existence de la classe de base nous permet de nous adresser à nos objets de façon générique #include "Chien.h" #include "Chat.h" #include <vector> int main() { Chien* chien = new Chien("Bella"); Chat* chat = new Chat("Minette"); // La collection des nos animaux std::vector<ADC*> nosAnimaux; nosAnimaux.push_back(chien); nosAnimaux.push_back(chat); // Quand on arrive a la maison les ADCs nous font la fête std::vector<ADC*>::iterator it; for ( it=nosAnimaux.begin(); it != nosAnimaux.end(); it++ ) (*it)->Parle(); // Il faut leur donner a manger (*it)->Mange(); // Et tout le monde s'occupe de son travail chien->MonteLaGarde(); chat->ChasseSouris(); } Les fonctions spécifiques ne peuvent pas être appelées de façon générique [localhost]> ./chezNous3 Bella: wouaf, wouaf !!! Minette: miaou, miaou !!! Bella mange des croquettes ProPlan Minette mange des boites Whiskas Bella monte la garde Minette chasse une souris

Si on achète un canari On ajoute une nouvelle classe dérivée de la classe ADC: #include “ADC.h” #include <string>  class Canari : public ADC { public: Canari(std::string nom); }; #include "Canari.h" #include <iostream> Canari::Canari(std::string nom) : ADC(nom) { } main4.cxx // ... #include "Canari.h" int main() { Canari* canari = new Canari("Lori"); nosAnimaux.push_back(canari); } [localhost]> ./chezNous4 Bella: wouaf, wouaf !!! Minette: miau, miau !!! Lori parle Bella mange des croquettes ProPlan Minette mange des boites Whiskas Lori mange Bella monte la garde Minette chasse une souris

Après 2. étape La classe de base (ADC) implante la donnée membre commune Les sous-classes (Chien, Chat) héritent de l'état définit l'interface pour des méthodes communes Les sous-classes (Chien, Chat) héritent de l'interface des méthodes et fournissent leurs propres définitions (implantations) implante des méthodes communes Les classes qui ne fournissent pas leurs propres définitions, ou implantations, (Canari) vont utiliser celles définies par la classe de base La classe de base nous permet d'appeler les fonctions propres aux objets par l'interface commune

3. étape Nous allons de nouveau ré-examiner les exigences de notre programme Imaginons que nous allons confier nos bêtes à notre voisin et lui demander de nous remplacer pendant nos vacances Notre programme l'aidera à savoir les besoins de nos animaux: Mais qu'est-ce que mange Lori? Notre classe de base nous a permis de ne pas spécifier les besoins de notre canari [localhost]> ./chezNous4 Bella: wouaf, wouaf !!! Minette: miau, miau !!! Lori parle Bella mange des croquettes ProPlan Minette mange des boites Whiskas Lori mange Bella monte la garde Minette chasse une souris

Fonctions virtuelles pures La classe de base peut obliger toutes les classes dérivées à implanter une fonction si elle la déclare comme une fonction virtuelle pure: #include "ADC.h" #include <iostream> ADC::ADC(std::string nom) : m_nom(nom) { } void ADC::Mange() { std::cout << m_nom << " mange" << std::endl; void ADC::Parle() { std::cout << m_nom << " parle" << std::endl; std::string ADC::Nom() { return m_nom; #include <string> class ADC { public: ADC(std::string nom); virtual void Mange() = 0; virtual void Parle() = 0; private: std::string m_nom; }; Fonctions déclarées virtuelle pure Les fonctions virtuelles pures n'ont pas la definition (l'implantation)

... Fonctions virtuelles pures On compile notre programme ... et il ne se compile pas ! Il est impossible de créer une instance de la classe qui n'a pas défini toutes les fonctions virtuelles pures héritées ainsi que de la classe qui a déclaré une fonction virtuelle Les classes desquelles on ne peut pas créer d' instance s'appellent les classes abstraites [localhost] > g++ -I. *.cxx -o chezNous4 main4.cxx: In function ‘int main()’: main4.cxx:10: error: cannot allocate an object of abstract type ‘Canari’ Canari.h:4: note: because the following virtual functions are pure within ‘Canari’: ADC.h:10: note: virtual void ADC::Mange() ADC.h:11: note: virtual void ADC::Parle()

Après 3. étape La classe de base (ADC) implante la donnée membre commune Les sous-classes (Chien, Chat) héritent de l'état définit l'interface pour des méthodes communes obligatoires Toutes les sous-classes (Chien, Chat, Canari) sont obligées de fournir leurs propres définitions (implantations) devient abstraite Il est impossible de créer une instance de la classe ADC La classe de base nous garantit que toutes les classes dérivées implantent les interfaces obligatoires

Si on nous donne un lapin ... Il faut ajouter le lapin dans notre famille de classes ADC Il faut alors définir des fonctions: Mange() - ok, le lapin mange des herbes sèches Parle() - mais le lapin ne parle pas ! Notre conception de la classe ADC n'était pas assez générique, comme la fonction Parle() n'est pas propre à tous animaux

... Si on nous donne un lapin On peut toujours définir la fonction et laisser le programme nous prévenir que la fonction qui a été appelée n'a pas de sens pour notre objet On peut évaluer la conception pour mieux refléter la réalité void Lapin::Parle() { std::cout << “Mais “ << Nom() << " ne parle pas !! " << std::endl; } ADC nom Mange() Classe des animaux de compagnie qui parlent ADCP Parle() Chien Mange() Parle() MonteLaGarde() Chat ChasseSouris() Chat ChasseSouris() Chat ChasseSouris() Chat Mange() Parle() ChasseSouris() Chat ChasseSouris() Chat ChasseSouris() Chat ChasseSouris() Canari Mange() Parle() Chat ChasseSouris() Lapin Mange() Chat ChasseSouris() Chat ChasseSouris()