56
Fabio Hernandez [email protected] Programmation Orientée Objet en C++ Programmation Orientée Objet en C++ 11ème Partie: Héritage 11ème Partie: Héritage

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

Embed Size (px)

DESCRIPTION

Support material for a continued education course "Introduction to object oriented programming in C++". In French.

Citation preview

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

Fabio [email protected]

Programmation Orientée Objet en C++Programmation Orientée Objet en C++

11ème Partie: Héritage11ème Partie: Héritage

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

© 1997-2003 Fabio HERNANDEZ345POO en C++: Héritage

Vue d'EnsembleVue d'Ensemble

Notions de base Types, variables, opérateursContrôle d'exécutionFonctionsMémoire dynamiqueQualité du logicielEvolution du modèle objet Objets et classesFonctions membresClasses génériquesHéritagePolymorphismeHéritage multipleEntrée/sortie

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

© 1997-2003 Fabio HERNANDEZ346POO en C++: Héritage

Table des MatièresTable des Matières

MotivationClassificationSpécialisationRedéfinition des fonctions membresConversions standardsContrôle d'accèsClasse abstraiteRedéfinition des opérateursRésumé

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

© 1997-2003 Fabio HERNANDEZ347POO en C++: Héritage

MotivationMotivation

Assez souvent, les nouveaux logiciels sont basés sur des développements précédentsPlusieurs approches

imitationraffinementcombinaison

Le modèle objet tient compte de ce fait et offre des mécanismes pour apporter une solution à ce problèmeLes techniques étudiées jusqu'à présent ne sont pas suffisantesLes classes constituent une bonne technique de décomposition en modules

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

© 1997-2003 Fabio HERNANDEZ348POO en C++: Héritage

Motivation (suite)Motivation (suite)

Les classes possèdent plusieurs des qualités demandées aux composants réutilisables

modules cohérentsséparation entre l'interface et l'implémentationflexibilité 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

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

© 1997-2003 Fabio HERNANDEZ349POO en C++: Héritage

Motivation (suite)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éritageentre classesL'héritage est un des composants fondamentaux de la technologie objet

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

© 1997-2003 Fabio HERNANDEZ350POO en C++: Héritage

Contrôle d'avancementContrôle d'avancement

MotivationClassificationSpécialisationRedéfinition des fonctions membresConversions standardsContrôle d'accèsClasse abstraiteRedéfinition des opérateursRésumé

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

© 1997-2003 Fabio HERNANDEZ351POO en C++: Héritage

ClassificationClassification

Nous voulons modéliser les comptes en banqueUn compte en banque a plusieurs caractéristiques intéressantes pour notre modèle

titulairenuméro d'identificationsoldedate de création

Quelques opérations sont souhaitables sur un compteobtenir le soldefaire un dépôtfaire un retraitfaire un virement sur un autre compte du même titulaire

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

© 1997-2003 Fabio HERNANDEZ352POO en C++: Héritage

Classification (suite)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();

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

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

© 1997-2003 Fabio HERNANDEZ353POO en C++: Héritage

Classification (suite)Classification (suite)

// Selectorsfloat 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_;

};

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

© 1997-2003 Fabio HERNANDEZ354POO en C++: Héritage

Classification (suite)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}

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

© 1997-2003 Fabio HERNANDEZ355POO en C++: Héritage

Classification (suite)Classification (suite)

Dans le monde réel il existe plusieurs types de comptes en banque

compte de chèquescompte d'épargneplan d'épargne logementplan 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{...};

...

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

© 1997-2003 Fabio HERNANDEZ356POO en C++: Héritage

Classification (suite)Classification (suite)

Comment refléter le fait que tous ces types de comptes ont des caractéristiques communes

titulairesoldenuméro d'identificationdate de création...

Mais aussi des caractéristiques particulières à chaque type comme

la (im)possibilité de retraittaux d'intérêtsolde minimum...

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

© 1997-2003 Fabio HERNANDEZ357POO en C++: Héritage

Classification (suite)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éristiquescommunesfaire 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 codeConsidé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, ...)

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

© 1997-2003 Fabio HERNANDEZ358POO en C++: Héritage

Classification (suite)Classification (suite)

class SavingAccount {

public:

// Constructors/Destructor

SavingAccount(const std::string& owner);

~SavingAccount();

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

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

© 1997-2003 Fabio HERNANDEZ359POO en C++: Héritage

Classification (suite)Classification (suite)

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

private:

// Data members

BankAccount account_;

float interestRate_;

};

La classeBankAccount est

contenue dans SavingAccount

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

© 1997-2003 Fabio HERNANDEZ360POO en C++: Héritage

Classification (suite)Classification (suite)

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

float SavingAccount::getBalance() const{

return account_.getBalance();}

bool SavingAccount::deposit(float amount){

return account_.deposit(amount);}

Ces méthodes délèguent leur implémentation

à l'attributaccount_

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

© 1997-2003 Fabio HERNANDEZ361POO en C++: Héritage

Classification (suite)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 similaireL'avantage de cette approche est la réutilisation sans duplication du codeSon principal inconvénient est qu'une modification dans la classe BankAccount suppose des modifications dans toutes les classes qui utilisent ses services (SavingAccount, CheckingAccount,...)

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

© 1997-2003 Fabio HERNANDEZ362POO en C++: Héritage

Classification (suite)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écessaireDans ce contexte nous pourrions définir la classe SavingAccount comme "une sorte de" BankAccountCe 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

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

© 1997-2003 Fabio HERNANDEZ363POO en C++: Héritage

Contrôle d'avancementContrôle d'avancement

MotivationClassificationSpécialisationRedéfinition des fonctions membresConversions standardsContrôle d'accèsClasse abstraiteRedéfinition des opérateursRésumé

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

© 1997-2003 Fabio HERNANDEZ364POO en C++: Héritage

SpécialisationSpécialisation

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

BankAccount

SavingAccount CheckingAccount

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

© 1997-2003 Fabio HERNANDEZ365POO en C++: Héritage

Spécialisation (suite)Spécialisation (suite)

class SavingAccount: public BankAccount {public:

// Constructors/Destructor

SavingAccount(const char* owner);~SavingAccount();

// Modifiers

bool setInterestRate(float newRate);

// Selectors

float getInterestRate() const;

private:

// Data members

float interestRate_;

};

Définition de SavingAccount

comme une spécialisation deBankAccount

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

© 1997-2003 Fabio HERNANDEZ366POO en C++: Héritage

Spécialisation (suite)Spécialisation (suite)

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

BankAccount

ownerName_: std::stringbalance_: floatcreationDate_: DateaccountNumber_: int

deposit: boolwithdraw:boolgetBalance: floatgetAccountNumber: intgetOwner: std::stringgetCreationDate: const Date&

SavingAccount

interestRate_: float

getInterestRate: floatsetInterestRate: bool

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

© 1997-2003 Fabio HERNANDEZ367POO en C++: Héritage

Spécialisation (suite)Spécialisation (suite)

Un objet déclaré commeSavingAccount account;

est composé des attributs de la classe BankAccount et de la classe SavingAccount

ownerName_: std::stringbalance_: floatcreationDate_: DateaccountNumber_: int

interestRate_: float

Attributs de la partie

BankAccount

Attributs de la partie

SavingAccountaccount

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

© 1997-2003 Fabio HERNANDEZ368POO en C++: Héritage

Spécialisation (suite)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);

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

© 1997-2003 Fabio HERNANDEZ369POO en C++: Héritage

Spécialisation (suite)Spécialisation (suite)

BankAccount

deposit: boolwithdraw: boolgetBalance: floatgetAccountNumber: intgetOwner: std::stringgetCreationDate: const Date&

SavingAccount

setInterestRate: boolgetInterestRate: float

Classe de base ouSuperClasse

Classe dérivée ou Sous-Classe

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

© 1997-2003 Fabio HERNANDEZ370POO en C++: Héritage

Spécialisation (suite)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){

interestRate_ = 0.0;}

Initialisation de la partie

BankAccount

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

© 1997-2003 Fabio HERNANDEZ371POO en C++: Héritage

Spécialisation (suite)Spécialisation (suite)

La liste d'initialisation des attributs est utilisée pour passer les arguments nécessaires au constructeur de la classe de baseDans cet exemple

BankAccount n'a pas de constructeur par défautSavingAccount 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 del'objet correspondante à la classe de base

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

© 1997-2003 Fabio HERNANDEZ372POO en C++: Héritage

Contrôle d'avancementContrôle d'avancement

MotivationClassificationSpécialisationRedéfinition des fonctions membresConversions standardsContrôle d'accèsClasse abstraiteRedéfinition des opérateursRésumé

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

© 1997-2003 Fabio HERNANDEZ373POO en C++: Héritage

Redéfinition des fonctions membresRedé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

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

© 1997-2003 Fabio HERNANDEZ374POO en C++: Héritage

Redéfinition des fonctions membres (suite)Redéfinition des fonctions membres (suite)

Certains types de comptes bancaires imposent des restrictions sur

le montant du retraitle solde minimum...

C'est le cas de notre compte d'épargne: un compte de ce type exige un solde minimumLa fonction membre BankAccount::withdraw ne peut pas être utilisée telle quelle par la classe SavingAccountSavingAccount doit définir sa propre opération SavingAccount::withdraw

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

© 1997-2003 Fabio HERNANDEZ375POO en C++: Héritage

Redéfinition des fonctions membres (suite)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

float getInterestRate() const;

private:

// Data members

float interestRate_;};

Redéfinition deBankAccount::withdraw

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

© 1997-2003 Fabio HERNANDEZ376POO en C++: Héritage

Redéfinition des fonctions membres (suite)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

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

© 1997-2003 Fabio HERNANDEZ377POO en C++: Héritage

Redéfinition des fonctions membres (suite)Redéfinition des fonctions membres (suite)

BankAccount

deposit: boolwithdraw: boolgetBalance: floatgetAccountNumber: intgetOwner: const std::stringcreationDate: const Date&

SavingAccount

setInterestRate: boolgetInterestRate: floatwithdraw: bool

La sous-classe spécialise une des fonctions membres

de la classe de base

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

© 1997-2003 Fabio HERNANDEZ378POO en C++: Héritage

Contrôle d'avancementContrôle d'avancement

MotivationClassificationSpécialisationRedéfinition des fonctions membresConversions standardsContrôle d'accèsClasse abstraiteRedéfinition des opérateursRésumé

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

© 1997-2003 Fabio HERNANDEZ379POO en C++: Héritage

Conversions standardsConversions 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 publicUn objet de la sous-classe peut être implicitement traité comme un objet de la classe de baseUn 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;

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

© 1997-2003 Fabio HERNANDEZ380POO en C++: Héritage

Conversions standards (suite)Conversions standards (suite)

Un objet d'une classe dérivée est composéd'une partie correspondante à la classe de based'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

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

© 1997-2003 Fabio HERNANDEZ381POO en C++: Héritage

Contrôle d'avancementContrôle d'avancement

MotivationClassificationSpécialisationRedéfinition des fonctions membresConversions standardsContrôle d'accèsClasse abstraiteRedéfinition des opérateursRésumé

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

© 1997-2003 Fabio HERNANDEZ382POO en C++: Héritage

Contrôle d'accèsContrô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_;

}

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

© 1997-2003 Fabio HERNANDEZ383POO en C++: Héritage

Contrôle d'accès (suite)Contrôle d'accès (suite)

Nous devons écrirefloat SavingAccount::computeProfit() const

{

return interestRate_ * getBalance();

}

Utilisation deBankAccount::getBalance()

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

© 1997-2003 Fabio HERNANDEZ384POO en C++: Héritage

Contrôle d'accès (suite)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 baseUn attribut ou méthode déclaré protected est accessible uniquement par les sous-classes

class BankAccount {public:

...

protected:

// Data membersstd::string& ownerName_;float balance_;Date creationDate_;int accountNumber_;

};

Ce mécanisme donne accès aux données

membres deBankAccount à toutes ses sous-

classes

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

© 1997-2003 Fabio HERNANDEZ385POO en C++: Héritage

Contrôle d'accès (suite)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 restreintBankAccount account;

account.balance_ = 200.0;

// COMPILATION ERROR: balance_ is protected

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

© 1997-2003 Fabio HERNANDEZ386POO en C++: Héritage

Contrôle d'accès (suite)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

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

© 1997-2003 Fabio HERNANDEZ387POO en C++: Héritage

Contrôle d'avancementContrôle d'avancement

MotivationClassificationSpécialisationRedéfinition des fonctions membresConversions standardsContrôle d'accèsClasse abstraiteRedéfinition des opérateursRésumé

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

© 1997-2003 Fabio HERNANDEZ388POO en C++: Héritage

Classe abstraiteClasse 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-classesEn 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élisonsAutrement dit, cette classe n'a lieu d'exister qu'en tant que composante d'une classe dérivée comme SavingAccount ou CheckingAccount

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

© 1997-2003 Fabio HERNANDEZ389POO en C++: Héritage

Classe abstraite (suite)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:

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

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

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

© 1997-2003 Fabio HERNANDEZ390POO en C++: Héritage

Classe abstraite (suite)Classe abstraite (suite)

protected:

// Constructors/DestructorBankAccount(const std::string& owner);

~BankAccount();

// Data members

std::string ownerName_;

float balance_;

Date creationDate_;

int accountNumber_;

};

Impossible de créer une instance de cette classe:

le constructeur et le destructeur sont

protégés

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

© 1997-2003 Fabio HERNANDEZ391POO en C++: Héritage

Classe abstraite (suite)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;

}

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

© 1997-2003 Fabio HERNANDEZ392POO en C++: Héritage

Contrôle d'avancementContrôle d'avancement

MotivationClassificationSpécialisationRedéfinition des fonctions membresConversions standardsContrôle d'accèsClasse abstraiteRedéfinition des opérateursRésumé

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

© 1997-2003 Fabio HERNANDEZ393POO en C++: Héritage

Redéfinition des opérateursRedéfinition des opérateurs

Une sous-classe hérite toutes les fonctions membres de sa classe de base sauf

les constructeursle destructeurles 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-classeLe destructeur est utilisé automatiquement à la destruction de l'objetLes opérateurs doivent être redéfinis par la sous-classe en appelant ceux de la classe de base

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

© 1997-2003 Fabio HERNANDEZ394POO en C++: Héritage

Redéfinition des opérateurs (suite)Redéfinition des opérateurs (suite)

class Base {

public:

...

bool operator==(const Base& aBase) const;

Base& operator=(const Base& aBase);

...

private:

int data_;

};

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

© 1997-2003 Fabio HERNANDEZ395POO en C++: Héritage

Redéfinition des opérateurs (suite)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;

}

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

© 1997-2003 Fabio HERNANDEZ396POO en C++: Héritage

Redéfinition des opérateurs (suite)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_;

};

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

© 1997-2003 Fabio HERNANDEZ397POO en C++: Héritage

Redéfinition des opérateurs (suite)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;

Base::operator=(aDerived);ratio_ = aDerived.ratio_;return *this;

}

Utilisation des opérateurs de la

classe de base dans l'implémentation des

opérateurs de la sous-classe

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

© 1997-2003 Fabio HERNANDEZ398POO en C++: Héritage

Contrôle d'avancementContrôle d'avancement

MotivationClassificationSpécialisationRedéfinition des fonctions membresConversions standardsContrôle d'accèsClasse abstraiteRedéfinition des opérateursRésumé

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

© 1997-2003 Fabio HERNANDEZ399POO en C++: Héritage

RésuméRésumé

L'héritage permet de définir de nouvelles classes par extension, spécialisation ou combinaison d'autres déjà définiesUne 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 baseDes 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'encapsulationUne classe abstraite en est une qui ne peut être utilisée que comme classe de baseLes opérateurs doivent être redéfinis par les sous-classes