Héritage et redéfinition de méthode

384 vues

Publié le

Ce cours présente la notion d'héritage entre classes qui permet de construire une relation de type "is-a". On crée une sous-classe à partir d'une super-classe, pour en hériter une partie de ses membres. On peut ensuite y ajouter des membres spécifiques. Ce cours présente également la redéfinition de méthodes, et comment utiliser les modificateurs de visibilité des membres.

Publié dans : Technologie
  • Soyez le premier à commenter

  • Soyez le premier à aimer ceci

Héritage et redéfinition de méthode

  1. 1. PO3T Programmation orientée objet Séance 3 Héritage et redéfinition de méthode Sébastien Combéfis, Quentin Lurkin lundi 5 octobre 2015
  2. 2. Ce(tte) œuvre est mise à disposition selon les termes de la Licence Creative Commons Attribution – Pas d’Utilisation Commerciale – Pas de Modification 4.0 International.
  3. 3. 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
  4. 4. 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
  5. 5. Héritage
  6. 6. 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
  7. 7. Représentation d’une paire (1) 1 public class Pair 2 { 3 private readonly double x, y; 4 5 public Pair ( double x, double y) 6 { 7 this.x = x; 8 this.y = y; 9 } 10 11 public bool isOrdered () 12 { 13 return x <= y; 14 } 15 16 public override string ToString () 17 { 18 return string.Format ("({0} , {1})", x, y); 19 } 20 } 7
  8. 8. 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); 3 4 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
  9. 9. 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
  10. 10. 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
  11. 11. 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 : Pair 2 { 3 public OrderedPair (double x, double y) : base (x <= y ? x : y, x <= y ? y : x) 4 { 5 6 } 7 } 11
  12. 12. 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); 3 4 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
  13. 13. Encapsulation et héritage Les membres privés sont limités à la classe 1 public class OrderedPair : Pair 2 { 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’ is inaccessible due to its protection level OrderedPair.cs (11 ,10): error CS0191: A readonly field ‘Cours3. Pair.x’ cannot be assigned to (except in a constructor or a variable initializer) 13
  14. 14. Et en C++... (1) 1 # include <iostream > 2 using namespace std; 3 4 class Pair 5 { 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 }; 14 15 Pair :: Pair (double x, double y) : x(x), y(y) 16 { 17 } 18 19 ostream & operator <<( ostream &str , Pair *p) 20 { 21 str << "(" << p->getX () << ", " << p->getY () << ")"; 22 return str; 23 } 14
  15. 15. 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 Pair 2 { 3 public: 4 OrderedPair (double x, double y); 5 }; 6 7 OrderedPair :: OrderedPair (double x, double y) : Pair (x <= y ? x : y, x <= y ? y : x) 8 { 9 } 15
  16. 16. Et en Java... (1) 1 public class Pair 2 { 3 private final double x, y; 4 5 public Pair ( double x, double y) 6 { 7 this.x = x; 8 this.y = y; 9 } 10 11 public boolean isOrdered () 12 { 13 return x <= y; 14 } 15 16 @Override 17 public String toString () 18 { 19 return String.format ("(%f, %f)", x, y); 20 } 21 } 16
  17. 17. 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 Pair 2 { 3 public OrderedPair (double x, double y) 4 { 5 super (x <= y ? x : y, x <= y ? y : x); 6 } 7 } 17
  18. 18. 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 = x 4 self.__y = y 5 6 def isordered(self): 7 return x <= y 8 9 def __str__(self): 10 return "({}, {})".format(self.__x , self.__y) 11 12 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
  19. 19. 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 Die 2 Pair OrderedPair 19
  20. 20. 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 = firstname 4 self.__lastname = lastname 5 6 def displayname(self): 7 return ’{} {}’.format(self.__firstname , self.__lastname) 8 9 def __str__(self): 10 return self.displayname () 11 12 p = Person(’John ’, ’Doe’) 13 print(p) John Doe 20
  21. 21. 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 = salary 5 6 @property 7 def salary(self): 8 return self.__salary 9 10 @salary.setter 11 def salary(self , value): 12 if value > 0: 13 self.__salary = value 14 15 def __str__(self): 16 return Person.__str__(self) + ’ ({} euros)’.format(self. __salary) 21
  22. 22. 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 Person 4 print(e.salary) # Spécifique à Employee 5 6 e.salary = 2800 7 print(e) Clémence Flémal (3200 euros) Clémence Flémal 3200 Clémence Flémal (2800 euros) 22
  23. 23. 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
  24. 24. Redéfinition
  25. 25. 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 ’) 4 5 class Cat(Mammal): 6 def yell(self): 7 print(’Meow ’) 8 9 class DuckBilledPlatypus (Mammal): 10 pass Cat DuckBilled... Mammal 25
  26. 26. 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 () 4 5 a.yell () 6 b.yell () 7 c.yell () Bwaaah Meow Bwaaah 26
  27. 27. 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 = price 4 5 def price(self): 6 return self.__price 7 8 class Beverage(Item): 9 def __init__(self , price): 10 Item.__init__(self , price) 11 12 def price(self): 13 return 1.06 * Item.price(self) 14 15 class ConsumerElectronics (Item): 16 def __init__(self , price): 17 Item.__init__(self , price) 18 19 def price(self): 20 return 1.21 * Item.price(self) 27
  28. 28. 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 = price 4 self._tax = 1 5 6 def tax(self): 7 return 1 8 9 def price(self): 10 return (1 + self.tax() / 100) * self.__price 11 12 class Beverage(Item): 13 def __init__(self , price): 14 Item.__init__(self , price) 15 16 def tax(self): # Redéfinition de la méthode tax () 17 return 6 28
  29. 29. 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 = price 4 self.__tax = 1 5 6 def price(self): 7 return (1 + self.__tax / 100) * self.__price 8 9 class Beverage(Item): 10 def __init__(self , price): 11 Item.__init__(self , price) 12 self.__tax = 6 29
  30. 30. 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 = price 4 self._tax = 1 5 6 def price(self): 7 return (1 + self._tax / 100) * self.__price 8 9 class ConsumerElectronics (Item): 10 def __init__(self , price): 11 Item.__init__(self , price) 12 self._tax = 21 13 14 macbookpro13 = ConsumerElectronics (1449.00) 15 macbookpro13 ._tax = -100 16 print( macbookpro13 .price ()) # Affiche combien ? 30
  31. 31. 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 A 2 { 3 private int a = 11; 4 public int b = 12; 5 public int c = 13; 6 7 private void secret () { System.out.println (42); } 8 public void print () { System.out.println ("Coucou " + a); } 9 } 10 11 class B extends A 12 { 13 private int a = 21; 14 public int c = 23; 15 } 31
  32. 32. Membres hérités (2) Qu’affiche chacune des instructions suivantes ? (ou invalide) 1 class Test 2 { 3 public static void main ( String [] args) 4 { 5 A a = new A(); 6 B b = new B(); 7 8 a.secret (); 9 a.print (); 10 System.out.println (a.a); 11 System.out.println (a.b); 12 System.out.println (a.c); 13 14 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
  33. 33. 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 C 2 { 3 private int a = 11; 4 protected int b = 12; 5 public int c = 13; 6 } 7 8 class D extends C 9 { 10 public void print () 11 { 12 System.out.println (a); 13 System.out.println (b); 14 System.out.println (c); 15 } 16 } 33
  34. 34. Visibilité protected (2) Qu’affiche chacune des instructions suivantes ? (ou invalide) 1 class Test 2 { 3 public static void main ( String [] args) 4 { 5 C c = new C(); 6 D d = new D(); 7 8 System.out.println (c.a); 9 System.out.println (c.b); 10 System.out.println (c.c); 11 12 System.out.println (d.a); 13 System.out.println (d.b); 14 System.out.println (d.c); 15 } 16 } 34
  35. 35. Crédits https://www.flickr.com/photos/quinnanya/3538871771 https://www.flickr.com/photos/axbom/8541624585 35

×