SlideShare une entreprise Scribd logo
1  sur  56
Télécharger pour lire hors ligne
Programmation Orientée Objet en C++
          11ème Partie: Héritage



              Fabio Hernandez
            Fabio.Hernandez@in2p3.fr
Vue d'Ensemble
   Notions de base
   Types, variables, opérateurs
   Contrôle d'exécution
   Fonctions
   Mémoire dynamique
   Qualité du logiciel
   Evolution du modèle objet
   Objets et classes
   Fonctions membres
   Classes génériques
   Héritage
   Polymorphisme
   Héritage multiple
   Entrée/sortie


POO en C++: Héritage              345        © 1997-2003 Fabio HERNANDEZ
Table des Matières

   Motivation
   Classification
   Spécialisation
   Redéfinition des fonctions membres
   Conversions standards
   Contrôle d'accès
   Classe abstraite
   Redéfinition des opérateurs
   Résumé




POO en C++: Héritage          346           © 1997-2003 Fabio HERNANDEZ
Motivation

   Assez souvent, les nouveaux logiciels sont basés sur des
   développements précédents
   Plusieurs approches
         imitation
         raffinement
         combinaison
   Le modèle objet tient compte de ce fait et offre des
   mécanismes pour apporter une solution à ce problème
   Les techniques étudiées jusqu'à présent ne sont pas suffisantes
   Les classes constituent une bonne technique de décomposition
   en modules


POO en C++: Héritage           347               © 1997-2003 Fabio HERNANDEZ
Motivation (suite)

   Les classes possèdent plusieurs des qualités demandées aux
   composants réutilisables
         modules cohérents
         séparation entre l'interface et l'implémentation
         flexibilité des classes génériques
   Davantage de qualités sont nécessaires pour atteindre les
   objectifs de réutilisation et extensibilité
   Nous avons besoin de mécanismes permettant d'exprimer les
   caractéristiques et le comportement communs existants dans
   des groupes de structures similaires, mais aussi de tenir
   compte des différences qui caractérisent les cas particuliers



POO en C++: Héritage                   348                  © 1997-2003 Fabio HERNANDEZ
Motivation (suite)

   Une classe peut être une extension, une spécialisation ou une
   combinaison d'autres classes
   Le modèle objet et les langages orientés objet fournissent des
   mécanismes offrant des solutions à ces besoins via l'héritage
   entre classes
   L'héritage est un des composants fondamentaux de la
   technologie objet




POO en C++: Héritage           349              © 1997-2003 Fabio HERNANDEZ
Contrôle d'avancement

   Motivation
   Classification
   Spécialisation
   Redéfinition des fonctions membres
   Conversions standards
   Contrôle d'accès
   Classe abstraite
   Redéfinition des opérateurs
   Résumé




POO en C++: Héritage            350        © 1997-2003 Fabio HERNANDEZ
Classification

   Nous voulons modéliser les comptes en banque
   Un compte en banque a plusieurs caractéristiques intéressantes
   pour notre modèle
         titulaire
         numéro d'identification
         solde
         date de création
   Quelques opérations sont souhaitables sur un compte
         obtenir le solde
         faire un dépôt
         faire un retrait
         faire un virement sur un autre compte du même titulaire


POO en C++: Héritage                   351                 © 1997-2003 Fabio HERNANDEZ
Classification (suite)

    Nous pouvons écrire l'interface de la classe compte en banque
   en C++ comme

          class BankAccount {
          public:
             // Constructors/Destructor
             BankAccount(const std::string& owner);
             ~BankAccount();

                // Modifiers
                bool deposit(float amount);
                bool withdraw(float amount);



POO en C++: Héritage               352           © 1997-2003 Fabio HERNANDEZ
Classification (suite)
                // Selectors
                float getBalance() const;
                int getAccountNumber() const;
                const std::string& getOwner() const;
                const Date& getCreationDate() const;

          private:
             // Data members
             std::string ownerName_;
             float balance_;
             Date creationDate_;
             int accountNumber_;
          };



POO en C++: Héritage               353             © 1997-2003 Fabio HERNANDEZ
Classification (suite)
   L’implémentation du constructeur et du destructeur de cette
   classe serait
          BankAccount::BankAccount(const std::string& owner)
          {
             ownerName_ = owner;
             balance_ = 0.0;
             accountNumber_ = . . .; // Do something to assign a
                                     // unique account number
          }

          BankAccount::~BankAccount()
          {
             // Nothing to do
          }




POO en C++: Héritage            354             © 1997-2003 Fabio HERNANDEZ
Classification (suite)

   Dans le monde réel il existe plusieurs types de comptes en
   banque
         compte de chèques
         compte d'épargne
         plan d'épargne logement
         plan de ...
   Notre modèle des comptes bancaires devrait refléter cette
   réalité
   Nous aurions tendance à modéliser chacun de ces types de
   comptes comme une classe C++
          class CheckingAccount {...};
          class SavingAccount{...};
          ...

POO en C++: Héritage               355          © 1997-2003 Fabio HERNANDEZ
Classification (suite)

   Comment refléter le fait que tous ces types de comptes ont des
   caractéristiques communes
         titulaire
         solde
         numéro d'identification
         date de création
         ...
   Mais aussi des caractéristiques particulières à chaque type
   comme
         la (im)possibilité de retrait
         taux d'intérêt
         solde minimum
         ...

POO en C++: Héritage                     356      © 1997-2003 Fabio HERNANDEZ
Classification (suite)

   Avec les mécanismes étudiés jusqu'à présent nous avons deux
   possibilités:
         dupliquer le code nécessaire pour modéliser ces caractéristiques
         communes
         faire en sorte que la classe modélisant les caractéristiques communes
         soit contenue dans les autres classes
   La première possibilité n'est pas envisageable parce qu'elle
   suppose tous les inconvénients de la duplication de code
   Considérons la deuxième: la classe SavingAccount contient un
   attribut de la classe BankAccount
         la mission de cet attribut est d'encapsuler toute l'information relative à
         un compte bancaire générique (titulaire, solde, ...)



POO en C++: Héritage                    357                  © 1997-2003 Fabio HERNANDEZ
Classification (suite)
          class SavingAccount {
          public:
             // Constructors/Destructor
             SavingAccount(const std::string& owner);
             ~SavingAccount();

                // Modifiers
                bool deposit(float amount);
                bool withdraw(float amount);
                bool setInterestRate(float newRate);




POO en C++: Héritage               358             © 1997-2003 Fabio HERNANDEZ
Classification (suite)
                // Selectors
                float getBalance() const;
                int getAccountNumber() const;
                const std::string& getOwner() const;
                const Date& getCreationDate() const;
                float getInterestRate() const;

          private:
             // Data members                      La classe
             BankAccount account_;            BankAccount est
             float interestRate_;               contenue dans
          };                                   SavingAccount




POO en C++: Héritage               359              © 1997-2003 Fabio HERNANDEZ
Classification (suite)

   L'implémentation des méthodes de la classe SavingAccount
   serait comme

          float SavingAccount::getBalance() const
          {
             return account_.getBalance();
          }                                            Ces méthodes
                                                       délèguent leur
          bool SavingAccount::deposit(float amount)   implémentation
          {                                             à l'attribut
                                                          account_
             return account_.deposit(amount);
          }




POO en C++: Héritage            360             © 1997-2003 Fabio HERNANDEZ
Classification (suite)

   Implémentation de la classe SavingAccount (suite)
          float SavingAccount::getInterestRate() const
          {
             return interestRate_;
          }
   La classe CheckingAccount pourrait être implémentée d'une
   façon similaire
   L'avantage de cette approche est la réutilisation sans
   duplication du code
   Son principal inconvénient est qu'une modification dans la
   classe BankAccount suppose des modifications dans toutes les
   classes qui utilisent ses services (SavingAccount,
   CheckingAccount,...)

POO en C++: Héritage             361            © 1997-2003 Fabio HERNANDEZ
Classification (suite)

   Le modèle objet fournit un mécanisme qui permet à une classe
   d'hériter les attributs et méthodes d'une autre classe et
   d'étendre ses fonctionnalités si nécessaire
   Dans ce contexte nous pourrions définir la classe
   SavingAccount comme "une sorte de" BankAccount
   Ce type de relation entre classes est connu comme une relation
   est-un (is-a), par opposition à une relation contient-un (has-a)
   Dans l'exemple précédent, la classe SavingAccount contient
   un BankAccount
   Regardons maintenant le mécanisme fournit par C++ pour
   exprimer la relation est-un


POO en C++: Héritage            362              © 1997-2003 Fabio HERNANDEZ
Contrôle d'avancement

   Motivation
   Classification
   Spécialisation
   Redéfinition des fonctions membres
   Conversions standards
   Contrôle d'accès
   Classe abstraite
   Redéfinition des opérateurs
   Résumé




POO en C++: Héritage            363        © 1997-2003 Fabio HERNANDEZ
Spécialisation

   Nous allons modéliser les classes SavingAccount et
   CheckingAccount comme une spécialisation de la classe
   BankAccount


                                   BankAccount




                       SavingAccount         CheckingAccount



POO en C++: Héritage                   364           © 1997-2003 Fabio HERNANDEZ
Spécialisation (suite)
          class SavingAccount: public BankAccount {
          public:
              // Constructors/Destructor
                                                           Définition de
             SavingAccount(const char* owner);
                                                        SavingAccount
             ~SavingAccount();
                                                            comme une
               // Modifiers                              spécialisation de
                                                          BankAccount
               bool setInterestRate(float newRate);

               // Selectors
               float getInterestRate() const;

          private:
              // Data members
             float interestRate_;
          };

POO en C++: Héritage                 365              © 1997-2003 Fabio HERNANDEZ
Spécialisation (suite)

   Un objet de la classe SavingAccount hérite les attributs et
   services de la classe BankAccount

                  BankAccount                   SavingAccount
       ownerName_: std::string
       balance_: float                     interestRate_: float
       creationDate_: Date
       accountNumber_: int                 getInterestRate: float
      deposit: bool                        setInterestRate: bool
      withdraw:bool
      getBalance: float
      getAccountNumber: int
      getOwner: std::string
      getCreationDate: const Date&

POO en C++: Héritage                 366               © 1997-2003 Fabio HERNANDEZ
Spécialisation (suite)

   Un objet déclaré comme
          SavingAccount account;
   est composé des attributs de la classe BankAccount et de la
   classe SavingAccount

            ownerName_: std::string         Attributs de la
            balance_: float                     partie
            creationDate_: Date             BankAccount
            accountNumber_: int

            interestRate_: float            Attributs de la
                                                partie
                       account              SavingAccount


POO en C++: Héritage                  367        © 1997-2003 Fabio HERNANDEZ
Spécialisation (suite)

   De façon similaire, un objet de la classe SavingAccount hérite
   les services de la classe BankAccount
   Nous pouvons donc écrire
          // Create a SavingAccount object
          SavingAccount account("Jacques Cousteau");
          // Deposit an amount into this account
          account.deposit(500.0);
          // Print its new balance
          cout << "The balance is " << account.getBalance();
          // Set its interest rate
          account.setInterestRate(0.03);




POO en C++: Héritage            368             © 1997-2003 Fabio HERNANDEZ
Spécialisation (suite)

                       BankAccount

         deposit: bool
                                               Classe de base ou
         withdraw: bool
                                                  SuperClasse
         getBalance: float
         getAccountNumber: int
         getOwner: std::string
         getCreationDate: const Date&



                  SavingAccount
                                               Classe dérivée ou
        setInterestRate: bool                     Sous-Classe
        getInterestRate: float
POO en C++: Héritage                 369             © 1997-2003 Fabio HERNANDEZ
Spécialisation (suite)

   L'implémentation de la classe SavingAccount est composée
   des fonctions membres particulières à cette classe
          bool SavingAccount::setInterestRate(float newRate)
          {
             interestRate_ = newRate;
             return true;
          }
          // Constructor
          SavingAccount::SavingAccount(const std::string& owner)
                           : BankAccount(owner)        Initialisation de
          {                                                la partie
                interestRate_ = 0.0;                    BankAccount
          }



POO en C++: Héritage               370            © 1997-2003 Fabio HERNANDEZ
Spécialisation (suite)

   La liste d'initialisation des attributs est utilisée pour passer les
   arguments nécessaires au constructeur de la classe de base
   Dans cet exemple
         BankAccount n'a pas de constructeur par défaut
         SavingAccount est une spécialisation de BankAccount
         Pour créer un objet de la classe SavingAccount il est nécessaire
         d'initialiser sa partie BankAccount
   Si la classe de base a un constructeur par défaut et la liste
   d'initialisation des attributs n'est pas spécifiée, c'est le
   constructeur par défaut qui sera utilisé pour créer la partie de
   l'objet correspondante à la classe de base



POO en C++: Héritage                  371                 © 1997-2003 Fabio HERNANDEZ
Contrôle d'avancement

   Motivation
   Classification
   Spécialisation
   Redéfinition des fonctions membres
   Conversions standards
   Contrôle d'accès
   Classe abstraite
   Redéfinition des opérateurs
   Résumé




POO en C++: Héritage            372        © 1997-2003 Fabio HERNANDEZ
Redéfinition des fonctions membres

   L'implémentation de BankAccount::withdraw pourrait être

          bool BankAccount::withdraw(float amount)
          {
             if (balance_ < amount)
                return false;

                balance_ -= amount;
                return true;
          }
   Celle-ci est une implémentation générique d'une opération de
   retrait


POO en C++: Héritage                  373       © 1997-2003 Fabio HERNANDEZ
Redéfinition des fonctions membres (suite)

   Certains types de comptes bancaires imposent des restrictions
   sur
         le montant du retrait
         le solde minimum
         ...
   C'est le cas de notre compte d'épargne: un compte de ce type
   exige un solde minimum
   La fonction membre BankAccount::withdraw ne peut pas
   être utilisée telle quelle par la classe SavingAccount
   SavingAccount doit définir sa propre opération
   SavingAccount::withdraw


POO en C++: Héritage             374           © 1997-2003 Fabio HERNANDEZ
Redéfinition des fonctions membres (suite)
          class SavingAccount: public BankAccount {
          public:
              // Constructors/Destructor
             SavingAccount(const std::string& owner);
             ~SavingAccount();

               // Modifiers
               bool setInterestRate(float newRate);
               bool withdraw(float amount);

               // Selectors
                                                      Redéfinition de
               float getInterestRate() const;
                                                 BankAccount::withdraw
          private:
              // Data members
             float interestRate_;
          };

POO en C++: Héritage                 375                © 1997-2003 Fabio HERNANDEZ
Redéfinition des fonctions membres (suite)
          bool SavingAccount::withdraw(float amount)
          {
             const float MinimumBalance = 500.0;
             if ((getBalance() - MinimumBalance) < amount)
                return false;

                return BankAccount::withdraw(amount);
          }
                                                 Appel explicite à la
                                                  fonction membre
                                                   withdraw de la
                                                    classe de base



POO en C++: Héritage               376              © 1997-2003 Fabio HERNANDEZ
Redéfinition des fonctions membres (suite)

                       BankAccount

         deposit: bool
         withdraw: bool
         getBalance: float
         getAccountNumber: int                  La sous-classe
         getOwner: const std::string          spécialise une des
         creationDate: const Date&           fonctions membres
                                               de la classe de
                                                     base

                  SavingAccount

        setInterestRate: bool
        getInterestRate: float
        withdraw: bool
POO en C++: Héritage                   377           © 1997-2003 Fabio HERNANDEZ
Contrôle d'avancement

   Motivation
   Classification
   Spécialisation
   Redéfinition des fonctions membres
   Conversions standards
   Contrôle d'accès
   Classe abstraite
   Redéfinition des opérateurs
   Résumé




POO en C++: Héritage            378        © 1997-2003 Fabio HERNANDEZ
Conversions standards

   Quelques conversions standards sont appliquées entre un objet
   d'une sous-classe et sa classe de base
         valable uniquement dans le cas d'héritage avec attribut public
   Un objet de la sous-classe peut être implicitement traité
   comme un objet de la classe de base
   Un pointeur (ou une référence) à un objet de la sous-classe peut
   être traité comme un pointeur (ou une référence) à un objet de
   la classe de base
          SavingAccount savingsAccount("Tantine Riche");
          // the 'savingsAccount' object is a kind of BankAccount
          BankAccount* bankAccountPtr = &savingsAccount;
          BankAccount& bankAccountRef = &savingsAccount;


POO en C++: Héritage                  379                 © 1997-2003 Fabio HERNANDEZ
Conversions standards (suite)

   Un objet d'une classe dérivée est composé
         d'une partie correspondante à la classe de base
         d'une partie spécifique à la sous-classe
   Ces conversions implicites sont acceptées parce qu’un objet
   d'une classe dérivée "contient" un objet de la classe de base




POO en C++: Héritage                   380                 © 1997-2003 Fabio HERNANDEZ
Contrôle d'avancement

   Motivation
   Classification
   Spécialisation
   Redéfinition des fonctions membres
   Conversions standards
   Contrôle d'accès
   Classe abstraite
   Redéfinition des opérateurs
   Résumé




POO en C++: Héritage            381        © 1997-2003 Fabio HERNANDEZ
Contrôle d'accès

   Bien que l'attribut BankAccount::balance_ soit un des
   composants de la classe SavingAccount, aucune des fonctions
   membres de SavingAccount n'y a accès, parce qu'il a été
   déclaré privé
   Si nous ajoutons la fonction membre computeProfit à la
   classe SavingAccount
          float SavingAccount::computeProfit() const
          {
             // COMPILATION ERROR: balance_ is a private
             // attribute of BankAccount
             return interestRate_ * balance_;
          }


POO en C++: Héritage            382             © 1997-2003 Fabio HERNANDEZ
Contrôle d'accès (suite)

   Nous devons écrire
          float SavingAccount::computeProfit() const
          {
             return interestRate_ * getBalance();
          }


                                    Utilisation de
                             BankAccount::getBalance()




POO en C++: Héritage               383               © 1997-2003 Fabio HERNANDEZ
Contrôle d'accès (suite)

   Il est parfois souhaitable qu'une fonction membre d'une sous-
   classe ait accès directement aux attributs de la classe de base
   Un attribut ou méthode déclaré protected est accessible
   uniquement par les sous-classes
          class BankAccount {
          public:
             ...
          protected:                    Ce mécanisme donne
             // Data members             accès aux données
             std::string& ownerName_;       membres de
             float balance_;              BankAccount à
             Date creationDate_;          toutes ses sous-
             int accountNumber_;              classes
          };

POO en C++: Héritage             384             © 1997-2003 Fabio HERNANDEZ
Contrôle d'accès (suite)

   Les fonctions membres de SavingAccount ont maintenant
   accès aux données membres de la partie de l ’objet
   correspondante à la classe BankAccount
          float SavingAccount::computeProfit() const
          {
             // OK: balance_ is a protected attribute
             // of BankAccount
             return interestRate_ * balance_;
          }
   Cependant l'accès à ces attributs reste toujours restreint
          BankAccount account;
          account.balance_ = 200.0;
                     // COMPILATION ERROR: balance_ is protected

POO en C++: Héritage             385            © 1997-2003 Fabio HERNANDEZ
Contrôle d'accès (suite)

   Un attribut(fonction) membre déclaré(e) protected est
   accessible par les fonctions membres d'une classe dérivée, mais
   il(elle) reste privé(e) pour le reste du programme




POO en C++: Héritage             386            © 1997-2003 Fabio HERNANDEZ
Contrôle d'avancement

   Motivation
   Classification
   Spécialisation
   Redéfinition des fonctions membres
   Conversions standards
   Contrôle d'accès
   Classe abstraite
   Redéfinition des opérateurs
   Résumé




POO en C++: Héritage            387        © 1997-2003 Fabio HERNANDEZ
Classe abstraite

   Nous avons créé la classe BankAccount afin de "factoriser" les
   attributs et le comportement communs de tous les types de
   comptes en banque dans le but de les réutiliser dans les sous-
   classes
   En conséquent, nous ne devrions pas avoir besoin de créer un
   objet de la classe BankAccount comme dans
          BankAccount account("Marcel Marceau");
          cout << account.getBalance() << endl;
   puisqu'il ne représente pas un objet du domaine du problème
   que nous modélisons
   Autrement dit, cette classe n'a lieu d'exister qu'en tant que
   composante d'une classe dérivée comme SavingAccount ou
   CheckingAccount


POO en C++: Héritage            388                © 1997-2003 Fabio HERNANDEZ
Classe abstraite (suite)

   Nous pouvons utiliser les mécanismes de contrôle d'accès pour
   empêcher qu'une instance de la classe BankAccount puisse
   être créée
          class BankAccount {
          public:
             // Modifiers
             bool deposit(float amount);
             bool withdraw(float amount);

                // Selectors
                float getBalance() const;
                int getAccountNumber() const;
                const std::string& getOwner() const;
                const Date& getCreationDate() const;


POO en C++: Héritage               389             © 1997-2003 Fabio HERNANDEZ
Classe abstraite (suite)

         protected:

              // Constructors/Destructor
              BankAccount(const std::string& owner);
              ~BankAccount();
                                             Impossible de créer une
              // Data members               instance de cette classe:
              std::string ownerName_;         le constructeur et le
              float balance_;
                                                destructeur sont
                                                    protégés
              Date creationDate_;
              int accountNumber_;
         };



POO en C++: Héritage              390               © 1997-2003 Fabio HERNANDEZ
Classe abstraite (suite)

   Maintenant, les services de la classe BankAccount ne peuvent
   être utilisés que par ses sous-classes

          #include "BankAccount.h"

          int main() {
             BankAccount account("Marcel Marceau");
                  // COMPILATION ERROR: the constructor
                  // of BankAccount is protected
             return 0;
          }




POO en C++: Héritage             391            © 1997-2003 Fabio HERNANDEZ
Contrôle d'avancement

   Motivation
   Classification
   Spécialisation
   Redéfinition des fonctions membres
   Conversions standards
   Contrôle d'accès
   Classe abstraite
   Redéfinition des opérateurs
   Résumé




POO en C++: Héritage            392        © 1997-2003 Fabio HERNANDEZ
Redéfinition des opérateurs

   Une sous-classe hérite toutes les fonctions membres de sa
   classe de base sauf
         les constructeurs
         le destructeur
         les opérateurs
   Les constructeurs ne sont pas hérités directement mais sont
   utilisés dans la liste d'initialisation des constructeurs de la
   sous-classe
   Le destructeur est utilisé automatiquement à la destruction de
   l'objet
   Les opérateurs doivent être redéfinis par la sous-classe en
   appelant ceux de la classe de base

POO en C++: Héritage               393           © 1997-2003 Fabio HERNANDEZ
Redéfinition des opérateurs (suite)
          class Base {
          public:
             ...
             bool operator==(const Base& aBase) const;
             Base& operator=(const Base& aBase);
             ...
          private:
             int data_;
          };




POO en C++: Héritage            394             © 1997-2003 Fabio HERNANDEZ
Redéfinition des opérateurs (suite)
          bool Base::operator==(const Base& aBase) const
          {
             return (data_ == aBase.data_) ? true : false;
          }

          Base& Base::operator=(const Base& aBase)
          {
             if (this == &aBase)
                return *this;

                data_ = aBase.data_;
                return *this;
          }



POO en C++: Héritage               395          © 1997-2003 Fabio HERNANDEZ
Redéfinition des opérateurs (suite)
          class Derived: public Base {
          public:
             ...
             bool operator==(const Derived& aDerived) const;
             Derived& operator=(const Derived& aDerived);
             ...
          private:
             float ratio_;
          };




POO en C++: Héritage            396             © 1997-2003 Fabio HERNANDEZ
Redéfinition des opérateurs (suite)
          bool Derived::operator==(const Derived& aDerived) const
          {
             return ( Base::operator==(aDerived) &&
                      (ratio_ == aDerived.ratio_)) ? true : false;
          }

          Derived& Derived::operator=(const Derived& aDerived)
          {
             if (this == &aDerived)
                return *this;                        Utilisation des
             Base::operator=(aDerived);             opérateurs de la
             ratio_ = aDerived.ratio_;
                                                  classe de base dans
                                                 l'implémentation des
             return *this;
                                                opérateurs de la sous-
          }                                               classe

POO en C++: Héritage              397               © 1997-2003 Fabio HERNANDEZ
Contrôle d'avancement

   Motivation
   Classification
   Spécialisation
   Redéfinition des fonctions membres
   Conversions standards
   Contrôle d'accès
   Classe abstraite
   Redéfinition des opérateurs
   Résumé




POO en C++: Héritage            398        © 1997-2003 Fabio HERNANDEZ
Résumé

   L'héritage permet de définir de nouvelles classes par
   extension, spécialisation ou combinaison d'autres déjà définies
   Une classe dérivée (ou sous-classe) hérite ses attributs et
   fonctions membres de la classe de base(ou super-classe)
   Une sous-classe peut redéfinir les fonctions membres de la
   classe de base
   Des mécanismes de contrôle d'accès permettent aux sous-
   classes d'accéder aux attributs de la classe de base tout en
   préservant l'encapsulation
   Une classe abstraite en est une qui ne peut être utilisée que
   comme classe de base
   Les opérateurs doivent être redéfinis par les sous-classes

POO en C++: Héritage           399               © 1997-2003 Fabio HERNANDEZ

Contenu connexe

Tendances

POO Java Chapitre 4 Heritage et Polymorphisme
POO Java Chapitre 4 Heritage et PolymorphismePOO Java Chapitre 4 Heritage et Polymorphisme
POO Java Chapitre 4 Heritage et PolymorphismeMouna Torjmen
 
Correction Examen 2016-2017 POO .pdf
Correction Examen 2016-2017 POO .pdfCorrection Examen 2016-2017 POO .pdf
Correction Examen 2016-2017 POO .pdfslimyaich3
 
Fondamentaux java
Fondamentaux javaFondamentaux java
Fondamentaux javaInes Ouaz
 
Présentation python
Présentation pythonPrésentation python
Présentation pythonSarah
 
Cours structures des données (langage c)
Cours structures des données (langage c)Cours structures des données (langage c)
Cours structures des données (langage c)rezgui mohamed
 
programmation orienté objet c++
programmation orienté objet c++programmation orienté objet c++
programmation orienté objet c++coursuniv
 
Chapitre4: Pointeurs et références
Chapitre4: Pointeurs et références Chapitre4: Pointeurs et références
Chapitre4: Pointeurs et références Aziz Darouichi
 
Cours de programmation en c
Cours de programmation en cCours de programmation en c
Cours de programmation en cbenouini rachid
 
Correction examen-java-avancé-1
Correction examen-java-avancé-1Correction examen-java-avancé-1
Correction examen-java-avancé-1vangogue
 
Cours python
Cours pythonCours python
Cours pythonsalmazen
 
Chap 6 : classes et interfaces
Chap 6 : classes et interfacesChap 6 : classes et interfaces
Chap 6 : classes et interfacesAziz Darouichi
 
POO Java Chapitre 6 Exceptions
POO Java  Chapitre 6 ExceptionsPOO Java  Chapitre 6 Exceptions
POO Java Chapitre 6 ExceptionsMouna Torjmen
 
Partie 12: Polymorphisme — Programmation orientée objet en C++
Partie 12: Polymorphisme — Programmation orientée objet en C++Partie 12: Polymorphisme — Programmation orientée objet en C++
Partie 12: Polymorphisme — Programmation orientée objet en C++Fabio Hernandez
 
Ch3-les structures conditionnelles.pdf
Ch3-les structures conditionnelles.pdfCh3-les structures conditionnelles.pdf
Ch3-les structures conditionnelles.pdfFadouaBouafifSamoud
 

Tendances (20)

POO Java Chapitre 4 Heritage et Polymorphisme
POO Java Chapitre 4 Heritage et PolymorphismePOO Java Chapitre 4 Heritage et Polymorphisme
POO Java Chapitre 4 Heritage et Polymorphisme
 
Correction Examen 2016-2017 POO .pdf
Correction Examen 2016-2017 POO .pdfCorrection Examen 2016-2017 POO .pdf
Correction Examen 2016-2017 POO .pdf
 
Fondamentaux java
Fondamentaux javaFondamentaux java
Fondamentaux java
 
Présentation python
Présentation pythonPrésentation python
Présentation python
 
Cours structures des données (langage c)
Cours structures des données (langage c)Cours structures des données (langage c)
Cours structures des données (langage c)
 
Programmation en C
Programmation en CProgrammation en C
Programmation en C
 
programmation orienté objet c++
programmation orienté objet c++programmation orienté objet c++
programmation orienté objet c++
 
Cours java
Cours javaCours java
Cours java
 
Chapitre4: Pointeurs et références
Chapitre4: Pointeurs et références Chapitre4: Pointeurs et références
Chapitre4: Pointeurs et références
 
COURS_PYTHON_22.ppt
COURS_PYTHON_22.pptCOURS_PYTHON_22.ppt
COURS_PYTHON_22.ppt
 
Cours de programmation en c
Cours de programmation en cCours de programmation en c
Cours de programmation en c
 
TP C++ : Correction
TP C++ : CorrectionTP C++ : Correction
TP C++ : Correction
 
Correction examen-java-avancé-1
Correction examen-java-avancé-1Correction examen-java-avancé-1
Correction examen-java-avancé-1
 
Chap1: Cours en C++
Chap1: Cours en C++Chap1: Cours en C++
Chap1: Cours en C++
 
Cours design pattern m youssfi partie 4 composite
Cours design pattern m youssfi partie 4 compositeCours design pattern m youssfi partie 4 composite
Cours design pattern m youssfi partie 4 composite
 
Cours python
Cours pythonCours python
Cours python
 
Chap 6 : classes et interfaces
Chap 6 : classes et interfacesChap 6 : classes et interfaces
Chap 6 : classes et interfaces
 
POO Java Chapitre 6 Exceptions
POO Java  Chapitre 6 ExceptionsPOO Java  Chapitre 6 Exceptions
POO Java Chapitre 6 Exceptions
 
Partie 12: Polymorphisme — Programmation orientée objet en C++
Partie 12: Polymorphisme — Programmation orientée objet en C++Partie 12: Polymorphisme — Programmation orientée objet en C++
Partie 12: Polymorphisme — Programmation orientée objet en C++
 
Ch3-les structures conditionnelles.pdf
Ch3-les structures conditionnelles.pdfCh3-les structures conditionnelles.pdf
Ch3-les structures conditionnelles.pdf
 

En vedette

Partie 8: Objets et Classes — Programmation orientée objet en C++
Partie 8: Objets et Classes — Programmation orientée objet en C++Partie 8: Objets et Classes — Programmation orientée objet en C++
Partie 8: Objets et Classes — Programmation orientée objet en C++Fabio Hernandez
 
Partie 7: Evolution du Modèle Objet — Programmation orientée objet en C++
Partie 7: Evolution du Modèle Objet — Programmation orientée objet en C++Partie 7: Evolution du Modèle Objet — Programmation orientée objet en C++
Partie 7: Evolution du Modèle Objet — Programmation orientée objet en C++Fabio Hernandez
 
Partie 4: Fonctions - Programmation orientée objet en C++
Partie 4: Fonctions - Programmation orientée objet en C++Partie 4: Fonctions - Programmation orientée objet en C++
Partie 4: Fonctions - Programmation orientée objet en C++Fabio Hernandez
 
Partie 10: Classes Génériques — Programmation orientée objet en C++
Partie 10: Classes Génériques — Programmation orientée objet en C++Partie 10: Classes Génériques — Programmation orientée objet en C++
Partie 10: Classes Génériques — Programmation orientée objet en C++Fabio Hernandez
 
Partie 2: Types, Variables, Opérateurs — Programmation orientée objet en C++
Partie 2: Types, Variables, Opérateurs — Programmation orientée objet en C++Partie 2: Types, Variables, Opérateurs — Programmation orientée objet en C++
Partie 2: Types, Variables, Opérateurs — Programmation orientée objet en C++Fabio Hernandez
 
Partie 1: Notions de base — Programmation orientée objet en C++
Partie 1: Notions de base — Programmation orientée objet en C++Partie 1: Notions de base — Programmation orientée objet en C++
Partie 1: Notions de base — Programmation orientée objet en C++Fabio Hernandez
 
Partie 6: Qualité du Logiciel — Programmation orientée objet en C++
Partie 6: Qualité du Logiciel — Programmation orientée objet en C++Partie 6: Qualité du Logiciel — Programmation orientée objet en C++
Partie 6: Qualité du Logiciel — Programmation orientée objet en C++Fabio Hernandez
 
Partie 3: Contrôle d'Exécution — Programmation orientée objet en C++
Partie 3: Contrôle d'Exécution — Programmation orientée objet en C++Partie 3: Contrôle d'Exécution — Programmation orientée objet en C++
Partie 3: Contrôle d'Exécution — Programmation orientée objet en C++Fabio Hernandez
 
Partie 14: Entrée/Sortie — Programmation orientée objet en C++
Partie 14: Entrée/Sortie — Programmation orientée objet en C++Partie 14: Entrée/Sortie — Programmation orientée objet en C++
Partie 14: Entrée/Sortie — Programmation orientée objet en C++Fabio Hernandez
 
Partie 5: Mémoire Dynamique — Programmation orientée objet en C++
Partie 5: Mémoire Dynamique — Programmation orientée objet en C++Partie 5: Mémoire Dynamique — Programmation orientée objet en C++
Partie 5: Mémoire Dynamique — Programmation orientée objet en C++Fabio Hernandez
 

En vedette (11)

Partie 8: Objets et Classes — Programmation orientée objet en C++
Partie 8: Objets et Classes — Programmation orientée objet en C++Partie 8: Objets et Classes — Programmation orientée objet en C++
Partie 8: Objets et Classes — Programmation orientée objet en C++
 
Partie 7: Evolution du Modèle Objet — Programmation orientée objet en C++
Partie 7: Evolution du Modèle Objet — Programmation orientée objet en C++Partie 7: Evolution du Modèle Objet — Programmation orientée objet en C++
Partie 7: Evolution du Modèle Objet — Programmation orientée objet en C++
 
Introduction à C++
Introduction à C++Introduction à C++
Introduction à C++
 
Partie 4: Fonctions - Programmation orientée objet en C++
Partie 4: Fonctions - Programmation orientée objet en C++Partie 4: Fonctions - Programmation orientée objet en C++
Partie 4: Fonctions - Programmation orientée objet en C++
 
Partie 10: Classes Génériques — Programmation orientée objet en C++
Partie 10: Classes Génériques — Programmation orientée objet en C++Partie 10: Classes Génériques — Programmation orientée objet en C++
Partie 10: Classes Génériques — Programmation orientée objet en C++
 
Partie 2: Types, Variables, Opérateurs — Programmation orientée objet en C++
Partie 2: Types, Variables, Opérateurs — Programmation orientée objet en C++Partie 2: Types, Variables, Opérateurs — Programmation orientée objet en C++
Partie 2: Types, Variables, Opérateurs — Programmation orientée objet en C++
 
Partie 1: Notions de base — Programmation orientée objet en C++
Partie 1: Notions de base — Programmation orientée objet en C++Partie 1: Notions de base — Programmation orientée objet en C++
Partie 1: Notions de base — Programmation orientée objet en C++
 
Partie 6: Qualité du Logiciel — Programmation orientée objet en C++
Partie 6: Qualité du Logiciel — Programmation orientée objet en C++Partie 6: Qualité du Logiciel — Programmation orientée objet en C++
Partie 6: Qualité du Logiciel — Programmation orientée objet en C++
 
Partie 3: Contrôle d'Exécution — Programmation orientée objet en C++
Partie 3: Contrôle d'Exécution — Programmation orientée objet en C++Partie 3: Contrôle d'Exécution — Programmation orientée objet en C++
Partie 3: Contrôle d'Exécution — Programmation orientée objet en C++
 
Partie 14: Entrée/Sortie — Programmation orientée objet en C++
Partie 14: Entrée/Sortie — Programmation orientée objet en C++Partie 14: Entrée/Sortie — Programmation orientée objet en C++
Partie 14: Entrée/Sortie — Programmation orientée objet en C++
 
Partie 5: Mémoire Dynamique — Programmation orientée objet en C++
Partie 5: Mémoire Dynamique — Programmation orientée objet en C++Partie 5: Mémoire Dynamique — Programmation orientée objet en C++
Partie 5: Mémoire Dynamique — Programmation orientée objet en C++
 

Similaire à Partie 11: Héritage — Programmation orientée objet en C++

Les nouveautés de C++11 : Ecrire du C++ Moderne
Les nouveautés de C++11 : Ecrire du C++ ModerneLes nouveautés de C++11 : Ecrire du C++ Moderne
Les nouveautés de C++11 : Ecrire du C++ ModerneMicrosoft
 
MIM Synchronization Services 2016 -> une solution économique pour créer, modi...
MIM Synchronization Services 2016 -> une solution économique pour créer, modi...MIM Synchronization Services 2016 -> une solution économique pour créer, modi...
MIM Synchronization Services 2016 -> une solution économique pour créer, modi...Identity Days
 
Formation C# - Cours 3 - Programmation objet
Formation C# - Cours 3 - Programmation objetFormation C# - Cours 3 - Programmation objet
Formation C# - Cours 3 - Programmation objetkemenaran
 
#J2Code2018 - Mettez du feu à vos applications avec CodeIgniter
#J2Code2018 - Mettez du feu à vos applications avec CodeIgniter#J2Code2018 - Mettez du feu à vos applications avec CodeIgniter
#J2Code2018 - Mettez du feu à vos applications avec CodeIgniterAtsé François-Xavier KOBON
 
Visual Basic 9.0 – Visual Studio 2008 Quoi De Neuf 2.0
Visual Basic 9.0 – Visual Studio 2008 Quoi De Neuf 2.0Visual Basic 9.0 – Visual Studio 2008 Quoi De Neuf 2.0
Visual Basic 9.0 – Visual Studio 2008 Quoi De Neuf 2.0Gregory Renard
 
Visual Basic 9.0 – Visual Studio 2008 Quoi De Neuf 2.0
Visual Basic 9.0 – Visual Studio 2008 Quoi De Neuf 2.0Visual Basic 9.0 – Visual Studio 2008 Quoi De Neuf 2.0
Visual Basic 9.0 – Visual Studio 2008 Quoi De Neuf 2.0Gregory Renard
 
Open close principle, on a dit étendre, pas extends !
Open close principle, on a dit étendre, pas extends !Open close principle, on a dit étendre, pas extends !
Open close principle, on a dit étendre, pas extends !Engineor
 
Qualité logicielle
Qualité logicielleQualité logicielle
Qualité logiciellecyrilgandon
 
Visual Studio 2008 Overview
Visual Studio 2008 OverviewVisual Studio 2008 Overview
Visual Studio 2008 OverviewGregory Renard
 
Visual Basic 9.0 – Visual Studio 2008 Quoi De Neuf 2.0
Visual Basic 9.0 – Visual Studio 2008 Quoi De Neuf 2.0Visual Basic 9.0 – Visual Studio 2008 Quoi De Neuf 2.0
Visual Basic 9.0 – Visual Studio 2008 Quoi De Neuf 2.0Gregory Renard
 
Soutenance Zend Framework vs Symfony
Soutenance Zend Framework vs SymfonySoutenance Zend Framework vs Symfony
Soutenance Zend Framework vs SymfonyVincent Composieux
 
Développer en natif avec C++11
Développer en natif avec C++11Développer en natif avec C++11
Développer en natif avec C++11Microsoft
 
Britair mdday2010
Britair mdday2010Britair mdday2010
Britair mdday2010MD DAY
 
C++ Metaprogramming : multidimensional typelist
C++ Metaprogramming : multidimensional typelistC++ Metaprogramming : multidimensional typelist
C++ Metaprogramming : multidimensional typelistVincent Agnus
 
Analyse et optimisation des performances du moteur SQL Serveur
Analyse et optimisation des performances du moteur SQL ServeurAnalyse et optimisation des performances du moteur SQL Serveur
Analyse et optimisation des performances du moteur SQL ServeurMicrosoft Technet France
 

Similaire à Partie 11: Héritage — Programmation orientée objet en C++ (20)

Les nouveautés de C++11 : Ecrire du C++ Moderne
Les nouveautés de C++11 : Ecrire du C++ ModerneLes nouveautés de C++11 : Ecrire du C++ Moderne
Les nouveautés de C++11 : Ecrire du C++ Moderne
 
MIM Synchronization Services 2016 -> une solution économique pour créer, modi...
MIM Synchronization Services 2016 -> une solution économique pour créer, modi...MIM Synchronization Services 2016 -> une solution économique pour créer, modi...
MIM Synchronization Services 2016 -> une solution économique pour créer, modi...
 
Formation C# - Cours 3 - Programmation objet
Formation C# - Cours 3 - Programmation objetFormation C# - Cours 3 - Programmation objet
Formation C# - Cours 3 - Programmation objet
 
Vs2008 Linq
Vs2008 LinqVs2008 Linq
Vs2008 Linq
 
#J2Code2018 - Mettez du feu à vos applications avec CodeIgniter
#J2Code2018 - Mettez du feu à vos applications avec CodeIgniter#J2Code2018 - Mettez du feu à vos applications avec CodeIgniter
#J2Code2018 - Mettez du feu à vos applications avec CodeIgniter
 
Visual Basic 9.0 – Visual Studio 2008 Quoi De Neuf 2.0
Visual Basic 9.0 – Visual Studio 2008 Quoi De Neuf 2.0Visual Basic 9.0 – Visual Studio 2008 Quoi De Neuf 2.0
Visual Basic 9.0 – Visual Studio 2008 Quoi De Neuf 2.0
 
Visual Basic 9.0 – Visual Studio 2008 Quoi De Neuf 2.0
Visual Basic 9.0 – Visual Studio 2008 Quoi De Neuf 2.0Visual Basic 9.0 – Visual Studio 2008 Quoi De Neuf 2.0
Visual Basic 9.0 – Visual Studio 2008 Quoi De Neuf 2.0
 
Open close principle, on a dit étendre, pas extends !
Open close principle, on a dit étendre, pas extends !Open close principle, on a dit étendre, pas extends !
Open close principle, on a dit étendre, pas extends !
 
POO-chapitre3.pptx
POO-chapitre3.pptxPOO-chapitre3.pptx
POO-chapitre3.pptx
 
Qualité logicielle
Qualité logicielleQualité logicielle
Qualité logicielle
 
Visual Studio 2008 Overview
Visual Studio 2008 OverviewVisual Studio 2008 Overview
Visual Studio 2008 Overview
 
Visual Basic 9.0 – Visual Studio 2008 Quoi De Neuf 2.0
Visual Basic 9.0 – Visual Studio 2008 Quoi De Neuf 2.0Visual Basic 9.0 – Visual Studio 2008 Quoi De Neuf 2.0
Visual Basic 9.0 – Visual Studio 2008 Quoi De Neuf 2.0
 
UML+Python
UML+PythonUML+Python
UML+Python
 
POO
POOPOO
POO
 
iTunes Stats
iTunes StatsiTunes Stats
iTunes Stats
 
Soutenance Zend Framework vs Symfony
Soutenance Zend Framework vs SymfonySoutenance Zend Framework vs Symfony
Soutenance Zend Framework vs Symfony
 
Développer en natif avec C++11
Développer en natif avec C++11Développer en natif avec C++11
Développer en natif avec C++11
 
Britair mdday2010
Britair mdday2010Britair mdday2010
Britair mdday2010
 
C++ Metaprogramming : multidimensional typelist
C++ Metaprogramming : multidimensional typelistC++ Metaprogramming : multidimensional typelist
C++ Metaprogramming : multidimensional typelist
 
Analyse et optimisation des performances du moteur SQL Serveur
Analyse et optimisation des performances du moteur SQL ServeurAnalyse et optimisation des performances du moteur SQL Serveur
Analyse et optimisation des performances du moteur SQL Serveur
 

Partie 11: Héritage — Programmation orientée objet en C++

  • 1. Programmation Orientée Objet en C++ 11ème Partie: Héritage Fabio Hernandez Fabio.Hernandez@in2p3.fr
  • 2. Vue d'Ensemble Notions de base Types, variables, opérateurs Contrôle d'exécution Fonctions Mémoire dynamique Qualité du logiciel Evolution du modèle objet Objets et classes Fonctions membres Classes génériques Héritage Polymorphisme Héritage multiple Entrée/sortie POO en C++: Héritage 345 © 1997-2003 Fabio HERNANDEZ
  • 3. Table des Matières Motivation Classification Spécialisation Redéfinition des fonctions membres Conversions standards Contrôle d'accès Classe abstraite Redéfinition des opérateurs Résumé POO en C++: Héritage 346 © 1997-2003 Fabio HERNANDEZ
  • 4. Motivation Assez souvent, les nouveaux logiciels sont basés sur des développements précédents Plusieurs approches imitation raffinement combinaison Le modèle objet tient compte de ce fait et offre des mécanismes pour apporter une solution à ce problème Les techniques étudiées jusqu'à présent ne sont pas suffisantes Les classes constituent une bonne technique de décomposition en modules POO en C++: Héritage 347 © 1997-2003 Fabio HERNANDEZ
  • 5. Motivation (suite) Les classes possèdent plusieurs des qualités demandées aux composants réutilisables modules cohérents séparation entre l'interface et l'implémentation flexibilité des classes génériques Davantage de qualités sont nécessaires pour atteindre les objectifs de réutilisation et extensibilité Nous avons besoin de mécanismes permettant d'exprimer les caractéristiques et le comportement communs existants dans des groupes de structures similaires, mais aussi de tenir compte des différences qui caractérisent les cas particuliers POO en C++: Héritage 348 © 1997-2003 Fabio HERNANDEZ
  • 6. Motivation (suite) Une classe peut être une extension, une spécialisation ou une combinaison d'autres classes Le modèle objet et les langages orientés objet fournissent des mécanismes offrant des solutions à ces besoins via l'héritage entre classes L'héritage est un des composants fondamentaux de la technologie objet POO en C++: Héritage 349 © 1997-2003 Fabio HERNANDEZ
  • 7. Contrôle d'avancement Motivation Classification Spécialisation Redéfinition des fonctions membres Conversions standards Contrôle d'accès Classe abstraite Redéfinition des opérateurs Résumé POO en C++: Héritage 350 © 1997-2003 Fabio HERNANDEZ
  • 8. Classification Nous voulons modéliser les comptes en banque Un compte en banque a plusieurs caractéristiques intéressantes pour notre modèle titulaire numéro d'identification solde date de création Quelques opérations sont souhaitables sur un compte obtenir le solde faire un dépôt faire un retrait faire un virement sur un autre compte du même titulaire POO en C++: Héritage 351 © 1997-2003 Fabio HERNANDEZ
  • 9. Classification (suite) Nous pouvons écrire l'interface de la classe compte en banque en C++ comme class BankAccount { public: // Constructors/Destructor BankAccount(const std::string& owner); ~BankAccount(); // Modifiers bool deposit(float amount); bool withdraw(float amount); POO en C++: Héritage 352 © 1997-2003 Fabio HERNANDEZ
  • 10. Classification (suite) // Selectors float getBalance() const; int getAccountNumber() const; const std::string& getOwner() const; const Date& getCreationDate() const; private: // Data members std::string ownerName_; float balance_; Date creationDate_; int accountNumber_; }; POO en C++: Héritage 353 © 1997-2003 Fabio HERNANDEZ
  • 11. Classification (suite) L’implémentation du constructeur et du destructeur de cette classe serait BankAccount::BankAccount(const std::string& owner) { ownerName_ = owner; balance_ = 0.0; accountNumber_ = . . .; // Do something to assign a // unique account number } BankAccount::~BankAccount() { // Nothing to do } POO en C++: Héritage 354 © 1997-2003 Fabio HERNANDEZ
  • 12. Classification (suite) Dans le monde réel il existe plusieurs types de comptes en banque compte de chèques compte d'épargne plan d'épargne logement plan de ... Notre modèle des comptes bancaires devrait refléter cette réalité Nous aurions tendance à modéliser chacun de ces types de comptes comme une classe C++ class CheckingAccount {...}; class SavingAccount{...}; ... POO en C++: Héritage 355 © 1997-2003 Fabio HERNANDEZ
  • 13. Classification (suite) Comment refléter le fait que tous ces types de comptes ont des caractéristiques communes titulaire solde numéro d'identification date de création ... Mais aussi des caractéristiques particulières à chaque type comme la (im)possibilité de retrait taux d'intérêt solde minimum ... POO en C++: Héritage 356 © 1997-2003 Fabio HERNANDEZ
  • 14. Classification (suite) Avec les mécanismes étudiés jusqu'à présent nous avons deux possibilités: dupliquer le code nécessaire pour modéliser ces caractéristiques communes faire en sorte que la classe modélisant les caractéristiques communes soit contenue dans les autres classes La première possibilité n'est pas envisageable parce qu'elle suppose tous les inconvénients de la duplication de code Considérons la deuxième: la classe SavingAccount contient un attribut de la classe BankAccount la mission de cet attribut est d'encapsuler toute l'information relative à un compte bancaire générique (titulaire, solde, ...) POO en C++: Héritage 357 © 1997-2003 Fabio HERNANDEZ
  • 15. Classification (suite) class SavingAccount { public: // Constructors/Destructor SavingAccount(const std::string& owner); ~SavingAccount(); // Modifiers bool deposit(float amount); bool withdraw(float amount); bool setInterestRate(float newRate); POO en C++: Héritage 358 © 1997-2003 Fabio HERNANDEZ
  • 16. Classification (suite) // Selectors float getBalance() const; int getAccountNumber() const; const std::string& getOwner() const; const Date& getCreationDate() const; float getInterestRate() const; private: // Data members La classe BankAccount account_; BankAccount est float interestRate_; contenue dans }; SavingAccount POO en C++: Héritage 359 © 1997-2003 Fabio HERNANDEZ
  • 17. Classification (suite) L'implémentation des méthodes de la classe SavingAccount serait comme float SavingAccount::getBalance() const { return account_.getBalance(); } Ces méthodes délèguent leur bool SavingAccount::deposit(float amount) implémentation { à l'attribut account_ return account_.deposit(amount); } POO en C++: Héritage 360 © 1997-2003 Fabio HERNANDEZ
  • 18. Classification (suite) Implémentation de la classe SavingAccount (suite) float SavingAccount::getInterestRate() const { return interestRate_; } La classe CheckingAccount pourrait être implémentée d'une façon similaire L'avantage de cette approche est la réutilisation sans duplication du code Son principal inconvénient est qu'une modification dans la classe BankAccount suppose des modifications dans toutes les classes qui utilisent ses services (SavingAccount, CheckingAccount,...) POO en C++: Héritage 361 © 1997-2003 Fabio HERNANDEZ
  • 19. Classification (suite) Le modèle objet fournit un mécanisme qui permet à une classe d'hériter les attributs et méthodes d'une autre classe et d'étendre ses fonctionnalités si nécessaire Dans ce contexte nous pourrions définir la classe SavingAccount comme "une sorte de" BankAccount Ce type de relation entre classes est connu comme une relation est-un (is-a), par opposition à une relation contient-un (has-a) Dans l'exemple précédent, la classe SavingAccount contient un BankAccount Regardons maintenant le mécanisme fournit par C++ pour exprimer la relation est-un POO en C++: Héritage 362 © 1997-2003 Fabio HERNANDEZ
  • 20. Contrôle d'avancement Motivation Classification Spécialisation Redéfinition des fonctions membres Conversions standards Contrôle d'accès Classe abstraite Redéfinition des opérateurs Résumé POO en C++: Héritage 363 © 1997-2003 Fabio HERNANDEZ
  • 21. Spécialisation Nous allons modéliser les classes SavingAccount et CheckingAccount comme une spécialisation de la classe BankAccount BankAccount SavingAccount CheckingAccount POO en C++: Héritage 364 © 1997-2003 Fabio HERNANDEZ
  • 22. Spécialisation (suite) class SavingAccount: public BankAccount { public: // Constructors/Destructor Définition de SavingAccount(const char* owner); SavingAccount ~SavingAccount(); comme une // Modifiers spécialisation de BankAccount bool setInterestRate(float newRate); // Selectors float getInterestRate() const; private: // Data members float interestRate_; }; POO en C++: Héritage 365 © 1997-2003 Fabio HERNANDEZ
  • 23. Spécialisation (suite) Un objet de la classe SavingAccount hérite les attributs et services de la classe BankAccount BankAccount SavingAccount ownerName_: std::string balance_: float interestRate_: float creationDate_: Date accountNumber_: int getInterestRate: float deposit: bool setInterestRate: bool withdraw:bool getBalance: float getAccountNumber: int getOwner: std::string getCreationDate: const Date& POO en C++: Héritage 366 © 1997-2003 Fabio HERNANDEZ
  • 24. Spécialisation (suite) Un objet déclaré comme SavingAccount account; est composé des attributs de la classe BankAccount et de la classe SavingAccount ownerName_: std::string Attributs de la balance_: float partie creationDate_: Date BankAccount accountNumber_: int interestRate_: float Attributs de la partie account SavingAccount POO en C++: Héritage 367 © 1997-2003 Fabio HERNANDEZ
  • 25. Spécialisation (suite) De façon similaire, un objet de la classe SavingAccount hérite les services de la classe BankAccount Nous pouvons donc écrire // Create a SavingAccount object SavingAccount account("Jacques Cousteau"); // Deposit an amount into this account account.deposit(500.0); // Print its new balance cout << "The balance is " << account.getBalance(); // Set its interest rate account.setInterestRate(0.03); POO en C++: Héritage 368 © 1997-2003 Fabio HERNANDEZ
  • 26. Spécialisation (suite) BankAccount deposit: bool Classe de base ou withdraw: bool SuperClasse getBalance: float getAccountNumber: int getOwner: std::string getCreationDate: const Date& SavingAccount Classe dérivée ou setInterestRate: bool Sous-Classe getInterestRate: float POO en C++: Héritage 369 © 1997-2003 Fabio HERNANDEZ
  • 27. Spécialisation (suite) L'implémentation de la classe SavingAccount est composée des fonctions membres particulières à cette classe bool SavingAccount::setInterestRate(float newRate) { interestRate_ = newRate; return true; } // Constructor SavingAccount::SavingAccount(const std::string& owner) : BankAccount(owner) Initialisation de { la partie interestRate_ = 0.0; BankAccount } POO en C++: Héritage 370 © 1997-2003 Fabio HERNANDEZ
  • 28. Spécialisation (suite) La liste d'initialisation des attributs est utilisée pour passer les arguments nécessaires au constructeur de la classe de base Dans cet exemple BankAccount n'a pas de constructeur par défaut SavingAccount est une spécialisation de BankAccount Pour créer un objet de la classe SavingAccount il est nécessaire d'initialiser sa partie BankAccount Si la classe de base a un constructeur par défaut et la liste d'initialisation des attributs n'est pas spécifiée, c'est le constructeur par défaut qui sera utilisé pour créer la partie de l'objet correspondante à la classe de base POO en C++: Héritage 371 © 1997-2003 Fabio HERNANDEZ
  • 29. Contrôle d'avancement Motivation Classification Spécialisation Redéfinition des fonctions membres Conversions standards Contrôle d'accès Classe abstraite Redéfinition des opérateurs Résumé POO en C++: Héritage 372 © 1997-2003 Fabio HERNANDEZ
  • 30. Redéfinition des fonctions membres L'implémentation de BankAccount::withdraw pourrait être bool BankAccount::withdraw(float amount) { if (balance_ < amount) return false; balance_ -= amount; return true; } Celle-ci est une implémentation générique d'une opération de retrait POO en C++: Héritage 373 © 1997-2003 Fabio HERNANDEZ
  • 31. Redéfinition des fonctions membres (suite) Certains types de comptes bancaires imposent des restrictions sur le montant du retrait le solde minimum ... C'est le cas de notre compte d'épargne: un compte de ce type exige un solde minimum La fonction membre BankAccount::withdraw ne peut pas être utilisée telle quelle par la classe SavingAccount SavingAccount doit définir sa propre opération SavingAccount::withdraw POO en C++: Héritage 374 © 1997-2003 Fabio HERNANDEZ
  • 32. Redéfinition des fonctions membres (suite) class SavingAccount: public BankAccount { public: // Constructors/Destructor SavingAccount(const std::string& owner); ~SavingAccount(); // Modifiers bool setInterestRate(float newRate); bool withdraw(float amount); // Selectors Redéfinition de float getInterestRate() const; BankAccount::withdraw private: // Data members float interestRate_; }; POO en C++: Héritage 375 © 1997-2003 Fabio HERNANDEZ
  • 33. Redéfinition des fonctions membres (suite) bool SavingAccount::withdraw(float amount) { const float MinimumBalance = 500.0; if ((getBalance() - MinimumBalance) < amount) return false; return BankAccount::withdraw(amount); } Appel explicite à la fonction membre withdraw de la classe de base POO en C++: Héritage 376 © 1997-2003 Fabio HERNANDEZ
  • 34. Redéfinition des fonctions membres (suite) BankAccount deposit: bool withdraw: bool getBalance: float getAccountNumber: int La sous-classe getOwner: const std::string spécialise une des creationDate: const Date& fonctions membres de la classe de base SavingAccount setInterestRate: bool getInterestRate: float withdraw: bool POO en C++: Héritage 377 © 1997-2003 Fabio HERNANDEZ
  • 35. Contrôle d'avancement Motivation Classification Spécialisation Redéfinition des fonctions membres Conversions standards Contrôle d'accès Classe abstraite Redéfinition des opérateurs Résumé POO en C++: Héritage 378 © 1997-2003 Fabio HERNANDEZ
  • 36. Conversions standards Quelques conversions standards sont appliquées entre un objet d'une sous-classe et sa classe de base valable uniquement dans le cas d'héritage avec attribut public Un objet de la sous-classe peut être implicitement traité comme un objet de la classe de base Un pointeur (ou une référence) à un objet de la sous-classe peut être traité comme un pointeur (ou une référence) à un objet de la classe de base SavingAccount savingsAccount("Tantine Riche"); // the 'savingsAccount' object is a kind of BankAccount BankAccount* bankAccountPtr = &savingsAccount; BankAccount& bankAccountRef = &savingsAccount; POO en C++: Héritage 379 © 1997-2003 Fabio HERNANDEZ
  • 37. Conversions standards (suite) Un objet d'une classe dérivée est composé d'une partie correspondante à la classe de base d'une partie spécifique à la sous-classe Ces conversions implicites sont acceptées parce qu’un objet d'une classe dérivée "contient" un objet de la classe de base POO en C++: Héritage 380 © 1997-2003 Fabio HERNANDEZ
  • 38. Contrôle d'avancement Motivation Classification Spécialisation Redéfinition des fonctions membres Conversions standards Contrôle d'accès Classe abstraite Redéfinition des opérateurs Résumé POO en C++: Héritage 381 © 1997-2003 Fabio HERNANDEZ
  • 39. Contrôle d'accès Bien que l'attribut BankAccount::balance_ soit un des composants de la classe SavingAccount, aucune des fonctions membres de SavingAccount n'y a accès, parce qu'il a été déclaré privé Si nous ajoutons la fonction membre computeProfit à la classe SavingAccount float SavingAccount::computeProfit() const { // COMPILATION ERROR: balance_ is a private // attribute of BankAccount return interestRate_ * balance_; } POO en C++: Héritage 382 © 1997-2003 Fabio HERNANDEZ
  • 40. Contrôle d'accès (suite) Nous devons écrire float SavingAccount::computeProfit() const { return interestRate_ * getBalance(); } Utilisation de BankAccount::getBalance() POO en C++: Héritage 383 © 1997-2003 Fabio HERNANDEZ
  • 41. Contrôle d'accès (suite) Il est parfois souhaitable qu'une fonction membre d'une sous- classe ait accès directement aux attributs de la classe de base Un attribut ou méthode déclaré protected est accessible uniquement par les sous-classes class BankAccount { public: ... protected: Ce mécanisme donne // Data members accès aux données std::string& ownerName_; membres de float balance_; BankAccount à Date creationDate_; toutes ses sous- int accountNumber_; classes }; POO en C++: Héritage 384 © 1997-2003 Fabio HERNANDEZ
  • 42. Contrôle d'accès (suite) Les fonctions membres de SavingAccount ont maintenant accès aux données membres de la partie de l ’objet correspondante à la classe BankAccount float SavingAccount::computeProfit() const { // OK: balance_ is a protected attribute // of BankAccount return interestRate_ * balance_; } Cependant l'accès à ces attributs reste toujours restreint BankAccount account; account.balance_ = 200.0; // COMPILATION ERROR: balance_ is protected POO en C++: Héritage 385 © 1997-2003 Fabio HERNANDEZ
  • 43. Contrôle d'accès (suite) Un attribut(fonction) membre déclaré(e) protected est accessible par les fonctions membres d'une classe dérivée, mais il(elle) reste privé(e) pour le reste du programme POO en C++: Héritage 386 © 1997-2003 Fabio HERNANDEZ
  • 44. Contrôle d'avancement Motivation Classification Spécialisation Redéfinition des fonctions membres Conversions standards Contrôle d'accès Classe abstraite Redéfinition des opérateurs Résumé POO en C++: Héritage 387 © 1997-2003 Fabio HERNANDEZ
  • 45. Classe abstraite Nous avons créé la classe BankAccount afin de "factoriser" les attributs et le comportement communs de tous les types de comptes en banque dans le but de les réutiliser dans les sous- classes En conséquent, nous ne devrions pas avoir besoin de créer un objet de la classe BankAccount comme dans BankAccount account("Marcel Marceau"); cout << account.getBalance() << endl; puisqu'il ne représente pas un objet du domaine du problème que nous modélisons Autrement dit, cette classe n'a lieu d'exister qu'en tant que composante d'une classe dérivée comme SavingAccount ou CheckingAccount POO en C++: Héritage 388 © 1997-2003 Fabio HERNANDEZ
  • 46. Classe abstraite (suite) Nous pouvons utiliser les mécanismes de contrôle d'accès pour empêcher qu'une instance de la classe BankAccount puisse être créée class BankAccount { public: // Modifiers bool deposit(float amount); bool withdraw(float amount); // Selectors float getBalance() const; int getAccountNumber() const; const std::string& getOwner() const; const Date& getCreationDate() const; POO en C++: Héritage 389 © 1997-2003 Fabio HERNANDEZ
  • 47. Classe abstraite (suite) protected: // Constructors/Destructor BankAccount(const std::string& owner); ~BankAccount(); Impossible de créer une // Data members instance de cette classe: std::string ownerName_; le constructeur et le float balance_; destructeur sont protégés Date creationDate_; int accountNumber_; }; POO en C++: Héritage 390 © 1997-2003 Fabio HERNANDEZ
  • 48. Classe abstraite (suite) Maintenant, les services de la classe BankAccount ne peuvent être utilisés que par ses sous-classes #include "BankAccount.h" int main() { BankAccount account("Marcel Marceau"); // COMPILATION ERROR: the constructor // of BankAccount is protected return 0; } POO en C++: Héritage 391 © 1997-2003 Fabio HERNANDEZ
  • 49. Contrôle d'avancement Motivation Classification Spécialisation Redéfinition des fonctions membres Conversions standards Contrôle d'accès Classe abstraite Redéfinition des opérateurs Résumé POO en C++: Héritage 392 © 1997-2003 Fabio HERNANDEZ
  • 50. Redéfinition des opérateurs Une sous-classe hérite toutes les fonctions membres de sa classe de base sauf les constructeurs le destructeur les opérateurs Les constructeurs ne sont pas hérités directement mais sont utilisés dans la liste d'initialisation des constructeurs de la sous-classe Le destructeur est utilisé automatiquement à la destruction de l'objet Les opérateurs doivent être redéfinis par la sous-classe en appelant ceux de la classe de base POO en C++: Héritage 393 © 1997-2003 Fabio HERNANDEZ
  • 51. Redéfinition des opérateurs (suite) class Base { public: ... bool operator==(const Base& aBase) const; Base& operator=(const Base& aBase); ... private: int data_; }; POO en C++: Héritage 394 © 1997-2003 Fabio HERNANDEZ
  • 52. Redéfinition des opérateurs (suite) bool Base::operator==(const Base& aBase) const { return (data_ == aBase.data_) ? true : false; } Base& Base::operator=(const Base& aBase) { if (this == &aBase) return *this; data_ = aBase.data_; return *this; } POO en C++: Héritage 395 © 1997-2003 Fabio HERNANDEZ
  • 53. Redéfinition des opérateurs (suite) class Derived: public Base { public: ... bool operator==(const Derived& aDerived) const; Derived& operator=(const Derived& aDerived); ... private: float ratio_; }; POO en C++: Héritage 396 © 1997-2003 Fabio HERNANDEZ
  • 54. Redéfinition des opérateurs (suite) bool Derived::operator==(const Derived& aDerived) const { return ( Base::operator==(aDerived) && (ratio_ == aDerived.ratio_)) ? true : false; } Derived& Derived::operator=(const Derived& aDerived) { if (this == &aDerived) return *this; Utilisation des Base::operator=(aDerived); opérateurs de la ratio_ = aDerived.ratio_; classe de base dans l'implémentation des return *this; opérateurs de la sous- } classe POO en C++: Héritage 397 © 1997-2003 Fabio HERNANDEZ
  • 55. Contrôle d'avancement Motivation Classification Spécialisation Redéfinition des fonctions membres Conversions standards Contrôle d'accès Classe abstraite Redéfinition des opérateurs Résumé POO en C++: Héritage 398 © 1997-2003 Fabio HERNANDEZ
  • 56. Résumé L'héritage permet de définir de nouvelles classes par extension, spécialisation ou combinaison d'autres déjà définies Une classe dérivée (ou sous-classe) hérite ses attributs et fonctions membres de la classe de base(ou super-classe) Une sous-classe peut redéfinir les fonctions membres de la classe de base Des mécanismes de contrôle d'accès permettent aux sous- classes d'accéder aux attributs de la classe de base tout en préservant l'encapsulation Une classe abstraite en est une qui ne peut être utilisée que comme classe de base Les opérateurs doivent être redéfinis par les sous-classes POO en C++: Héritage 399 © 1997-2003 Fabio HERNANDEZ