Héritage et redéfinition de méthode

Post on 21-Mar-2017

338 views 0 download

Transcript of Héritage et redéfinition de méthode

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

Ce(tte) œuvre est mise à disposition selon les termes de la Licence Creative CommonsAttribution – Pas d’Utilisation Commerciale – Pas de Modification 4.0 International.

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

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

Héritage

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Redéfinition

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

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

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

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

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

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

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

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

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

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

Crédits

https://www.flickr.com/photos/quinnanya/3538871771https://www.flickr.com/photos/axbom/8541624585

35