Download - Héritage et redéfinition de méthode
![Page 1: Héritage et redéfinition de méthode](https://reader034.vdocuments.site/reader034/viewer/2022042520/58d07ff11a28ab012d8b4b41/html5/thumbnails/1.jpg)
PO3T Programmation orientée objet
Séance 3
Héritage etredéfinition de méthode
Sébastien Combéfis, Quentin Lurkin lundi 5 octobre 2015
![Page 2: Héritage et redéfinition de méthode](https://reader034.vdocuments.site/reader034/viewer/2022042520/58d07ff11a28ab012d8b4b41/html5/thumbnails/2.jpg)
Ce(tte) œuvre est mise à disposition selon les termes de la Licence Creative CommonsAttribution – Pas d’Utilisation Commerciale – Pas de Modification 4.0 International.
![Page 3: Héritage et redéfinition de méthode](https://reader034.vdocuments.site/reader034/viewer/2022042520/58d07ff11a28ab012d8b4b41/html5/thumbnails/3.jpg)
Rappels
Trois types de relation entre classes
Composition et agrégation (has-a)
Relation uses
Couplage et cohésion de classes
Immuabilité des objets
Partage de références d’objet en tout sécurité (alias)
Copie de surface et en profondeur
3
![Page 4: Héritage et redéfinition de méthode](https://reader034.vdocuments.site/reader034/viewer/2022042520/58d07ff11a28ab012d8b4b41/html5/thumbnails/4.jpg)
Objectifs
Relation d’héritage entre classes
Sous-classe (classe fille)
Comparaison composition/héritage
Héritage multiple
Redéfinition de méthodes
Redéfinition
Accès aux membres de la super-classe (classe mère)
Membres protected
4
![Page 5: Héritage et redéfinition de méthode](https://reader034.vdocuments.site/reader034/viewer/2022042520/58d07ff11a28ab012d8b4b41/html5/thumbnails/5.jpg)
Héritage
![Page 6: Héritage et redéfinition de méthode](https://reader034.vdocuments.site/reader034/viewer/2022042520/58d07ff11a28ab012d8b4b41/html5/thumbnails/6.jpg)
Héritage
Définir une classe à partir d’une autre
Sous-ensemble des membres communs entre les deux classes
Possibilité de mettre en place du polymorphisme
Un même objet peut prendre plusieurs formes selon le contexte
Nouveau niveau de visibilité pour les membres d’une classe
Membres privés mais hérités
6
![Page 7: Héritage et redéfinition de méthode](https://reader034.vdocuments.site/reader034/viewer/2022042520/58d07ff11a28ab012d8b4b41/html5/thumbnails/7.jpg)
Représentation d’une paire (1)
1 public class Pair2 {3 private readonly double x, y;45 public Pair ( double x, double y)6 {7 this .x = x;8 this .y = y;9 }
1011 public bool isOrdered ()12 {13 return x <= y;14 }1516 public override string ToString ()17 {18 return string . Format ("({0} , {1})", x, y);19 }20 }
7
![Page 8: Héritage et redéfinition de méthode](https://reader034.vdocuments.site/reader034/viewer/2022042520/58d07ff11a28ab012d8b4b41/html5/thumbnails/8.jpg)
Représentation d’une paire (2)
Une paire est composée de deux nombres réels
On peut obtenir la somme de ses nombres
Méthode bool isOrdered() teste si la paire est ordonnée
1 Pair p1 = new Pair (12 , 7);2 Pair p2 = new Pair (-2, 0);34 Console . WriteLine ( string . Format ("{0}: {1}", p1 , p1. isOrdered ()));5 Console . WriteLine ( string . Format ("{0}: {1}", p2 , p2. isOrdered ()));
(12 , 7): False(-2, 0): True
8
![Page 9: Héritage et redéfinition de méthode](https://reader034.vdocuments.site/reader034/viewer/2022042520/58d07ff11a28ab012d8b4b41/html5/thumbnails/9.jpg)
Extension d’une classe (1)
La classe OrderedPair représente une paire ordonnée
Sous-ensemble des membres communs entre les deux classes
Variante de la classe Pair
Le constructeur ré-ordonne les valeurs
Toujours ordonnée
Hériter une partie de la classe Pair
Éviter de la duplication de code, source d’erreur
9
![Page 10: Héritage et redéfinition de méthode](https://reader034.vdocuments.site/reader034/viewer/2022042520/58d07ff11a28ab012d8b4b41/html5/thumbnails/10.jpg)
Extension d’une classe (2)
Une sous-classe étend une super-classe
La sous-classe hérite de tous les membres de la super-classe
Pair
OrderedPair
10
![Page 11: Héritage et redéfinition de méthode](https://reader034.vdocuments.site/reader034/viewer/2022042520/58d07ff11a28ab012d8b4b41/html5/thumbnails/11.jpg)
Représentation d’une paire ordonnée (1)
Une sous-classe (classe dérivée, classe enfant) étend une autre
Déclaration de la super-classe (classe étendu, classe parent)
Constructeur d’une sous-classe appelle celui de la classe parent
Construire la super-classe avant la sous-classe
1 public class OrderedPair : Pair2 {3 public OrderedPair ( double x, double y) : base (x <= y ? x : y,
x <= y ? y : x)4 {56 }7 }
11
![Page 12: Héritage et redéfinition de méthode](https://reader034.vdocuments.site/reader034/viewer/2022042520/58d07ff11a28ab012d8b4b41/html5/thumbnails/12.jpg)
Représentation d’une paire ordonnée (2)
Une paire ordonnée ré-ordonne les nombres réels
Au moment d’appeler le constructeur de la super-classe
La méthode bool isOrdered() renvoie toujours true
1 OrderedPair o1 = new OrderedPair (12 , 7);2 OrderedPair o2 = new OrderedPair (-2, 0);34 Console . WriteLine ( string . Format ("{0}: {1}", o1 , o1. isOrdered ()));5 Console . WriteLine ( string . Format ("{0}: {1}", o2 , o2. isOrdered ()));
(7, 12): True(-2, 0): True
12
![Page 13: Héritage et redéfinition de méthode](https://reader034.vdocuments.site/reader034/viewer/2022042520/58d07ff11a28ab012d8b4b41/html5/thumbnails/13.jpg)
Encapsulation et héritage
Les membres privés sont limités à la classe
1 public class OrderedPair : Pair2 {3 public OrderedPair ( double x, double y) : base (x, y)4 {5 if (x > y)6 {7 this .x = y;8 this .y = x;9 }
10 }11 }
OrderedPair .cs (11 ,10): error CS0122 : ‘Cours3 .Pair.x’ isinaccessible due to its protection levelOrderedPair .cs (11 ,10): error CS0191 : A readonly field ‘Cours3 .Pair.x’ cannot be assigned to ( except in a constructor or avariable initializer )
13
![Page 14: Héritage et redéfinition de méthode](https://reader034.vdocuments.site/reader034/viewer/2022042520/58d07ff11a28ab012d8b4b41/html5/thumbnails/14.jpg)
Et en C++... (1)
1 # include <iostream >2 using namespace std;34 class Pair5 {6 private :7 const double x, y;8 public :9 Pair ( double x, double y);
10 double getX () { return x; }11 double getY () { return y; }12 bool isOrdered () { return x <= y; }13 };1415 Pair :: Pair ( double x, double y) : x(x), y(y)16 {17 }1819 ostream & operator <<( ostream &str , Pair *p)20 {21 str << "(" << p->getX () << ", " << p->getY () << ")";22 return str;23 }
14
![Page 15: Héritage et redéfinition de méthode](https://reader034.vdocuments.site/reader034/viewer/2022042520/58d07ff11a28ab012d8b4b41/html5/thumbnails/15.jpg)
Et en C++... (2)
Signaler l’extension avec en précisant la super-classe après :
Mot réservé public nécessaire pour le polymorphisme
Appel au constructeur de la super-classe via son nom
1 class OrderedPair : public Pair2 {3 public :4 OrderedPair ( double x, double y);5 };67 OrderedPair :: OrderedPair ( double x, double y) : Pair (x <= y ? x :
y, x <= y ? y : x)8 {9 }
15
![Page 16: Héritage et redéfinition de méthode](https://reader034.vdocuments.site/reader034/viewer/2022042520/58d07ff11a28ab012d8b4b41/html5/thumbnails/16.jpg)
Et en Java... (1)
1 public class Pair2 {3 private final double x, y;45 public Pair ( double x, double y)6 {7 this .x = x;8 this .y = y;9 }
1011 public boolean isOrdered ()12 {13 return x <= y;14 }1516 @Override17 public String toString ()18 {19 return String . format ("(%f, %f)", x, y);20 }21 }
16
![Page 17: Héritage et redéfinition de méthode](https://reader034.vdocuments.site/reader034/viewer/2022042520/58d07ff11a28ab012d8b4b41/html5/thumbnails/17.jpg)
Et en Java... (2)
Signaler l’extension avec extends
Appel du constructeur de la super-classe avec super
Doit être la première instruction du constructeur
1 public class OrderedPair extends Pair2 {3 public OrderedPair ( double x, double y)4 {5 super (x <= y ? x : y, x <= y ? y : x);6 }7 }
17
![Page 18: Héritage et redéfinition de méthode](https://reader034.vdocuments.site/reader034/viewer/2022042520/58d07ff11a28ab012d8b4b41/html5/thumbnails/18.jpg)
Et en Python...
Signaler la classe étendue entre parenthèses
Appel du constructeur de la super-classe avec super()
1 class Pair:2 def __init__ (self , x, y):3 self.__x = x4 self.__y = y56 def isordered (self):7 return x <= y89 def __str__ (self):
10 return "({} , {})". format (self.__x , self.__y)1112 class OrderedPair (Pair):13 def __init__ (self , x, y):14 super (). __init__ (x if x <= y else y, y if x <= y else x)
18
![Page 19: Héritage et redéfinition de méthode](https://reader034.vdocuments.site/reader034/viewer/2022042520/58d07ff11a28ab012d8b4b41/html5/thumbnails/19.jpg)
Has-a versus is-a
Une paire de dé est composée de deux dés
PairOfDice has-a Die
Une paire ordonnée est une paire
OrderedPair is-a Pair
PairOfDice Die2
Pair
OrderedPair
19
![Page 20: Héritage et redéfinition de méthode](https://reader034.vdocuments.site/reader034/viewer/2022042520/58d07ff11a28ab012d8b4b41/html5/thumbnails/20.jpg)
Représenter une personne
Une personne est caractérisée par un prénom et un nom
Deux variables d’instances __firstname et __lastname
1 class Person :2 def __init__ (self , firstname , lastname ):3 self. __firstname = firstname4 self. __lastname = lastname56 def displayname (self):7 return ’{} {} ’. format (self. __firstname , self. __lastname )89 def __str__ (self):
10 return self. displayname ()1112 p = Person (’John ’, ’Doe ’)13 print (p)
John Doe
20
![Page 21: Héritage et redéfinition de méthode](https://reader034.vdocuments.site/reader034/viewer/2022042520/58d07ff11a28ab012d8b4b41/html5/thumbnails/21.jpg)
Représenter un employé (1)
Classe Person étendue par classe Employee
Un employé est une personne avec un employeur et un salaire
1 class Employee ( Person ):2 def __init__ (self , firstname , lastname , salary =0):3 Person . __init__ (self , firstname , lastname )4 self. __salary = salary56 @property7 def salary (self):8 return self. __salary9
10 @salary.setter11 def salary (self , value ):12 if value > 0:13 self. __salary = value1415 def __str__ (self):16 return Person . __str__ (self) + ’ ({} euros )’. format (self.
__salary )
21
![Page 22: Héritage et redéfinition de méthode](https://reader034.vdocuments.site/reader034/viewer/2022042520/58d07ff11a28ab012d8b4b41/html5/thumbnails/22.jpg)
Représenter un employé (2)
Accesseur salary spécifique aux employés
Définit dans la sous-classe, mais pas dans la super-classe
1 e = Employee (’Clémence ’, ’Flémal ’, 3200)2 print (e)3 print (e. displayname ()) # Hérité de Person4 print (e. salary ) # Spécifique à Employee56 e. salary = 28007 print (e)
Clémence Flémal (3200 euros )Clémence Flémal3200Clémence Flémal (2800 euros )
22
![Page 23: Héritage et redéfinition de méthode](https://reader034.vdocuments.site/reader034/viewer/2022042520/58d07ff11a28ab012d8b4b41/html5/thumbnails/23.jpg)
Héritage multiple
Étendre plusieurs classes en même temps
Pas autorisé par tous les langages de programmation
Conflits possibles entre les membres publics hérités
1 class Minister ( Functionary , Representative ):2 ’’’Un ministre est un fonctionnaire et un représentant ’’’3 # ...
Functionary Representative
Mammal
23
![Page 24: Héritage et redéfinition de méthode](https://reader034.vdocuments.site/reader034/viewer/2022042520/58d07ff11a28ab012d8b4b41/html5/thumbnails/24.jpg)
Redéfinition
![Page 25: Héritage et redéfinition de méthode](https://reader034.vdocuments.site/reader034/viewer/2022042520/58d07ff11a28ab012d8b4b41/html5/thumbnails/25.jpg)
Redéfinition (1)
Rédéfinir une méthode définie dans la super-classe
1 class Mammal :2 def yell(self):3 print (’Bwaaah ’)45 class Cat( Mammal ):6 def yell(self):7 print (’Meow ’)89 class DuckBilledPlatypus ( Mammal ):
10 pass
Cat DuckBilled...
Mammal
25
![Page 26: Héritage et redéfinition de méthode](https://reader034.vdocuments.site/reader034/viewer/2022042520/58d07ff11a28ab012d8b4b41/html5/thumbnails/26.jpg)
Redéfinition (2)
Spécialiser la méthode pour la sous-classe
La méthode exécutée est toujours la plus spécifique
1 a = Mammal ()2 b = Cat ()3 c = DuckBilledPlatypus ()45 a.yell ()6 b.yell ()7 c.yell ()
BwaaahMeowBwaaah
26
![Page 27: Héritage et redéfinition de méthode](https://reader034.vdocuments.site/reader034/viewer/2022042520/58d07ff11a28ab012d8b4b41/html5/thumbnails/27.jpg)
Accès à la super-classe
Accès aux membres de la super-classe depuis une sous-classe
Avec le mot réservé super ou via le nom de la super-classe
1 class Item:2 def __init__ (self , price ):3 self. __price = price45 def price (self):6 return self. __price78 class Beverage (Item):9 def __init__ (self , price ):
10 Item. __init__ (self , price )1112 def price (self):13 return 1.06 * Item. price (self)1415 class ConsumerElectronics (Item):16 def __init__ (self , price ):17 Item. __init__ (self , price )1819 def price (self):20 return 1.21 * Item. price (self)
27
![Page 28: Héritage et redéfinition de méthode](https://reader034.vdocuments.site/reader034/viewer/2022042520/58d07ff11a28ab012d8b4b41/html5/thumbnails/28.jpg)
Restructuration
Diminuer la redondance de code !
Calcul du prix taxes comprises similaire dans les différentes classes
1 class Item:2 def __init__ (self , price ):3 self. __price = price4 self._tax = 156 def tax(self):7 return 189 def price (self):
10 return (1 + self.tax () / 100) * self. __price1112 class Beverage (Item):13 def __init__ (self , price ):14 Item. __init__ (self , price )1516 def tax(self): # Redéfinition de la méthode tax ()17 return 6
28
![Page 29: Héritage et redéfinition de méthode](https://reader034.vdocuments.site/reader034/viewer/2022042520/58d07ff11a28ab012d8b4b41/html5/thumbnails/29.jpg)
Masquage (1)
Masquage des variables d’instance
Impossible de redéfinir une variable d’instance
Chaque classe possède sa propre copie de la variable
1 class Item:2 def __init__ (self , price ):3 self. __price = price4 self. __tax = 156 def price (self):7 return (1 + self. __tax / 100) * self. __price89 class Beverage (Item):
10 def __init__ (self , price ):11 Item. __init__ (self , price )12 self. __tax = 6
29
![Page 30: Héritage et redéfinition de méthode](https://reader034.vdocuments.site/reader034/viewer/2022042520/58d07ff11a28ab012d8b4b41/html5/thumbnails/30.jpg)
Masquage (2)
Pas de masquage en brisant l’encapsulation
Convention Python, préfixe _ pour pas touche
1 class Item:2 def __init__ (self , price ):3 self. __price = price4 self._tax = 156 def price (self):7 return (1 + self._tax / 100) * self. __price89 class ConsumerElectronics (Item):
10 def __init__ (self , price ):11 Item. __init__ (self , price )12 self._tax = 211314 macbookpro13 = ConsumerElectronics (1449.00)15 macbookpro13 ._tax = -10016 print ( macbookpro13 . price ()) # Affiche combien ?
30
![Page 31: Héritage et redéfinition de méthode](https://reader034.vdocuments.site/reader034/viewer/2022042520/58d07ff11a28ab012d8b4b41/html5/thumbnails/31.jpg)
Membres hérités (1)
Héritage de certaines variables d’instance et méthodes
Les variables d’instance sont toutes héritées
Seules les méthodes publiques sont héritées
1 class A2 {3 private int a = 11;4 public int b = 12;5 public int c = 13;67 private void secret () { System .out. println (42); }8 public void print () { System .out. println (" Coucou " + a); }9 }
1011 class B extends A12 {13 private int a = 21;14 public int c = 23;15 }
31
![Page 32: Héritage et redéfinition de méthode](https://reader034.vdocuments.site/reader034/viewer/2022042520/58d07ff11a28ab012d8b4b41/html5/thumbnails/32.jpg)
Membres hérités (2)
Qu’affiche chacune des instructions suivantes ? (ou invalide)
1 class Test2 {3 public static void main ( String [] args)4 {5 A a = new A();6 B b = new B();78 a. secret ();9 a. print ();
10 System .out. println (a.a);11 System .out. println (a.b);12 System .out. println (a.c);1314 b. secret ();15 b. print ();16 System .out. println (b.a);17 System .out. println (b.b);18 System .out. println (b.c);19 }20 }
32
![Page 33: Héritage et redéfinition de méthode](https://reader034.vdocuments.site/reader034/viewer/2022042520/58d07ff11a28ab012d8b4b41/html5/thumbnails/33.jpg)
Visibilité protected (1)
Un membre protected est privé et public à la fois
Privé pour le monde extérieur
Public pour les sous-classes
1 class C2 {3 private int a = 11;4 protected int b = 12;5 public int c = 13;6 }78 class D extends C9 {
10 public void print ()11 {12 System .out. println (a);13 System .out. println (b);14 System .out. println (c);15 }16 }
33
![Page 34: Héritage et redéfinition de méthode](https://reader034.vdocuments.site/reader034/viewer/2022042520/58d07ff11a28ab012d8b4b41/html5/thumbnails/34.jpg)
Visibilité protected (2)
Qu’affiche chacune des instructions suivantes ? (ou invalide)
1 class Test2 {3 public static void main ( String [] args)4 {5 C c = new C();6 D d = new D();78 System .out. println (c.a);9 System .out. println (c.b);
10 System .out. println (c.c);1112 System .out. println (d.a);13 System .out. println (d.b);14 System .out. println (d.c);15 }16 }
34
![Page 35: Héritage et redéfinition de méthode](https://reader034.vdocuments.site/reader034/viewer/2022042520/58d07ff11a28ab012d8b4b41/html5/thumbnails/35.jpg)
Crédits
https://www.flickr.com/photos/quinnanya/3538871771https://www.flickr.com/photos/axbom/8541624585
35