La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

Le polymorphisme.

Présentations similaires


Présentation au sujet: "Le polymorphisme."— Transcription de la présentation:

1 Le polymorphisme

2 Polymorphisme : Principe général
Le terme de polymorphisme décrit la caractéristique d’un élément qui peut prendre plusieurs formes, comme l’eau qui se trouve à l’état solide, liquide ou gazeux. . Principe de substitution définit par Liskov : Il doit être possible de substituer n’importe quel objet instance d’une sous-classe à n’importe quel objet instance d’une superclasse sans que la sémantique du programme écrit dans les termes de la superclasse ne soit affectée.

3 Principe général : exemple
Animal Lion Tigre Ours Soit Clarance un objet instance de la classe Lion. Clarance peut se substituer à des objets de la classe Animal Clarance : Lion Substitution de Clarance à A1 Clarance : Animal A1 : Animal

4 Polymorphisme et informatique
En informatique, le polymorphisme désigne un concept de la théorie des types, selon lequel un nom d’objet peut désigner des instances de classes différentes issues d’une même arborescence Animal Lion Tigre Ours Soit Clarance le nom d’un objet de type Animal. Clarance peut donc désigner des instances des classes Animal, Lion, Tigre et Ours.

5 Exemple en JAVA class Animal {} class Lion extends Animal { }
class Tigre extends Animal { } class Ours extends Animal { } public class Essai { public static void main (String args []) {Animal clarance; Lion l; clarance = new Lion(); clarance = new Tigre(); clarance = new Animal(); Lion l = new Animal (); } Déclaration des types Clarance désigne une instance de la classe Lion Pas possible car il y a incompatibilité de type

6 Le polymorphisme d’opération (1)
Les interactions entre objets sont décrites selon les termes des spécifications définies, non pas dans les classes des objets, mais dans leurs superclasses. Animal {abstrait} Dormir() {abstrait} Lion Tigre Ours Dormir() Dormir() Dormir() Dormir ( ) { Sur le ventre } Dormir ( ) { Sur le dos } Dormir ( ) { Dans un arbre }

7 Le polymorphisme d’opération (2)
Chaque sous-classe hérite de la spécification des opérations de ses surperclasses, mais a la possibilité de modifier localement le comportement de ces opérations, afin de mieux prendre en compte les particularismes liés à un niveau d’abstraction donné. De ce point de vue, une opération donnée est polymorphe puisque sa réalisation peut prendre plusieurs formes.

8 Le polymorphisme d’opération : exemple en JAVA
abstract class Animal { abstract public void dormir ( ); } class Lion extends Animal { public void dormir ( ) {System.out.println ("Sur le ventre"); }} class Tigre extends Animal { public void dormir ( ) {System.out.println ("Sur le dos"); }} class Ours extends Animal { public void dormir ( ) {System.out.println ("Dans les arbres"); }} public class Essai { public static void main (String args []) {Animal a = new Lion ( ); a.dormir(); a = new Tigre ( ); a.dormir(); a = new Lion ( ); a.dormir(); }

9 Le polymorphisme d’opération : remarque
Le polymorphisme n’influence pas l’analyse, mais en dépend : sa mise en œuvre efficace repose sur l’identification de mécanismes abstraits, applicables de manière uniforme à des objets instances de sous-classes différentes. Il ne faut pas penser l’analyse en termes de polymorphisme, mais en terme d’abstraction et ainsi, par effet de bord bénéfique de celle-ci, rendre possible le polymorphisme.

10 Exemple 1 sur le transtypage (1)
Animal : {abstrait} Dormir() {abstrait} Lion Tigre Ours Dormir() Manger() Dormir() Dormir() Dormir ( ) { Sur le dos } Dormir ( ) { Dans un arbre } Dormir ( ) { Sur le ventre }

11 Exemple1 sur le transtypage (2)
Soit Clarance un nom d’objet de type Animal. Nous pouvons donc avoir : Clarance : Lion Clarance étant une instance de type Lion, nous désirons faire manger le lion Manger() Clarance : Lion :Soigneur Ceci n’est pas possible en conception, car l’opération manger() n’est pas définie dans la classe Animal et que Clarance est de type Animal. Or clarance est bien un objet de la classe Lion, il faut donc transformer le type de l’objet clarance.

12 Exemple1 sur le transtypage (3)
abstract class Animal { abstract public void dormir (); } class Lion extends Animal { public void dormir () {System.out.println ("Sur le ventre"); } public void manger () {System.out.println ("Le lion mange");}} public class Essai { public static void main (String args []) { Animal clarance = new Lion(); clarance.dormir(); ((Lion)clarance).manger(); } Opération de transtypage (cast)

13 Exemple2 sur le transtypage (1)
Dormir ( ) { Un animal dort } Animal Dormir() Lion Tigre Ours Dormir() Manger() Dormir() Dormir() Dormir ( ) { Sur le dos } Dormir ( ) { Dans un arbre } Dormir ( ) { Sur le ventre } La méthode Dormir() est réalisée dans la classe Animal, elle est donc redéfinie dans les classes Lion, Tigre et Ours. On parle de redéfinition de méthode.

14 Exemple2 sur le transtypage (2)
On désire faire dormir clarance mais en tant que Animal et pas comme un lion. Dormir en tant que Animal :soigneur clarance:Lion

15 Exemple2 sur le transtypage (3)
class Animal { public void dormir ( ){System.out.println ("Un animal dort");} } class Lion extends Animal { public void dormir ( ) {System.out.println ("Sur le ventre"); } public void manger ( ) {System.out.println ("Le lion mange");}} public class Soigneur { public static void main (String args []) { Animal clarance = new Lion( ); ((Lion)clarance).manger( ); clarance.dormir ( ) ; ((Animal)clarance).dormir( ); } Utilisation de la méthode dormir() de la classe Lion On indique à clarance d’utiliser la méthode dormir de la classe Animal

16 Autre situation où l’on exploite le polymorphisme
Point Point (X,Y : entier) { coordonnéeX <- X; coordonnéeY <- Y} - CoordonneeX : entier - CoordonneeY : entier <<constructeur>> + Point (X,Y:entier) + <<selecteur>> + affiche() + identifie () affiche() { identifie(); afficher (" Mes coordonnées sont : " CoordonnéeX + " " + CoordonnéeY);} identifie () { Afficher " Je suis un point " } Pointcoloré (X,Y,Z : entier) { Point(X,Y) couleur <- Y} Pointcoloré - Couleur : entier <<constructeur>> + Pointcolore (Y,Y,Z:entier) + <<selecteur>> + identifie () identifie () { Afficher " Je suis un point coloré de couleur " + couleur }

17 Traduction en JAVA Je suis un point colore de couleur 2
class Point { private int coordonneeX, coordonneeY; public Point (int x, int y) { coordonneeX=x;coordonneeY=y;} public void affiche() { identifie(); System.out.println ("Mes coordonnees sont : " + coordonneeX + " " + coordonneeY);} public void identifie() { System.out.println ("Je suis un point ");} } class Pointcolore extends Point { private int couleur; public Pointcolore (int x, int y, int z) { super(x,y); couleur = z; } public void identifie () { System.out.println ("Je suis un point colore de couleur " + couleur);} public class essai1 { public static void main (String args []) { Pointcolore pc = new Pointcolore (8,6,2); pc.affiche(); } Je suis un point colore de couleur 2 Mes coordonnees sont 8 2

18 Déroulement des appels
Création d’une instance I1 de la classe PointColoré. Exécution du constructeur de la classe PoinColoré. Exécution du constructeur de la classe point I1 a pour coordonneeX la valeur 8 I1 a pour coordonneeY la valeur 6 - I1 a pour couleur la valeur 2 Exécution de la méthode affiche de la classe PointColoré. Cette méthode est héritée de la classe Point. Exécution de la méthode identifie de la classe PoinColoré Affichage « je suis un point colore de couleur 2 » Affichage « Mes coordonnees sont 8 2 »

19 Surcharge d’opérations
Certains langages autorisent l’emploi d’un même nom pour désigner une famille d’opérations, avec un profil de paramètres différent pour chaque opération. Enfant Manger() Manger( Lentement : Booléen) Manger (Lentement : Booléen, Comme_un_cochon : booléen)

20 Surcharge d’opérations : exemple 1 (1)
Dormir ( durée : entier) { Un animal dort pendant « durée »} Animal Dormir(durée) Lion Tigre Ours Dormir() Manger() Dormir() Dormir() Dormir ( ) { Sur le dos } Dormir ( ) { Dans un arbre } Dormir ( ) { Sur le ventre } La méthode Dormir(durée) est héritée. Aussi la méthode Dormir() surcharge (surdéfinie) cette dernière.

21 Surcharge d’opérations : exemple 1 (2)
class Animal { public void dormir (int duree ) {System.out.println ("Un animal dort" + duree);} } class Lion extends Animal { public void dormir ( ) {System.out.println ("Sur le ventre"); } public void manger ( ) {System.out.println ("Le lion mange");} class Tigre extends Animal { public void dormir ( ) {System.out.println ("Sur le dos"); }} class Ours extends Animal { public void dormir ( ) {System.out.println ("Dans les arbres"); }} public class Essai { public static void main (String args []) { Lion a = new Lion( ); a.dormir(12); a.dormir( ); On sait quelle méthode déclenchée grâce aux paramètres

22 Surcharge d’opérations : exemple 1 (3)
class Animal { public void dormir (int duree ) {System.out.println ("Un animal dort" + duree);} } class Lion extends Animal { public void dormir ( ) {System.out.println ("Sur le ventre"); } public void manger ( ) {System.out.println ("Le lion mange");} class Tigre extends Animal { public void dormir ( ) {System.out.println ("Sur le dos"); }} class Ours extends Animal { public void dormir ( ) {System.out.println ("Dans les arbres"); }} public class Essai { public static void main (String args []) { Animal a = new Lion( ); a.dormir(12); ((Lion)a).dormir( ) Problème de typage et non de polymorphisme

23 Surcharge d’opérations : exemple 1 (4)
JAVA est langage typé. Aussi la phase de compilation tient compte des types. La phase d’interprétation réalisera le polymorphisme. Lors de la compilation, le compilateur reconnaît la variable a comme étant de type Animal. Lors de l’interprétation, cette variable contiendra une instance de la classe Lion. L’instruction a.dormir() n’est pas reconnue par le compilateur car dans la définition du type Animal, il n’y a pas de méthode dormir() et cette méthode n’est pas définie dans les sur-types de la classe (autrement dit la méthode dormir() n’est pas héritée par la classe Animal). L’instruction ((Lion)a).dormir() est reconnue par le compilateur car le type de la variable a est modifié en type Lion qui lui contient la méthode dormir().

24 Surcharge d’opérations : exemple 2 (1)
Ami ( Animal a) { cet animal est ami avec un animal} Animal Ami(Animal) Lion Ami(Lion) Ami (Lion l) { Un lion est ami avec un lion}

25 Surcharge d’opérations : exemple 2 (2)
class Animal { public void ami (Animal a) {System.out.println ("Un animal est ami avec un animal");} } class Lion extends Animal { public void ami (Lion l) { System.out.println ("Un lion est ami avec un lion");} public class Essai { public static void main (String args []) { Animal a = new Lion(); Lion l = new Lion(); l.ami(a); Un animal est ami d’un animal

26 Surcharge d’opérations : exemple 2 (3)
La surcharge est toujours résolue statiquement par les compilateur. Elle est sans rapport avec la liaison dynamique. Etude de la ligne : a.ami(l). 1ére étape : la compilation - l est reconnu de type Lion - a est reconnu de type Animal même si elle contient une instance de la classe Lion - On examine donc la méthode ami de la classe animal. Celle-ci doit posséder comme argument une variable de type Animal ou de tout sous-type de la classe Animal. l étant de type Lion qui est un sous-type de Animal, le compilateur décide d’utiliser cette méthode et non la méthode ami associé à la classe Lion.

27 Surcharge d’opérations : exemple 2 (4)
2ème étape : l’interprétation - la variable a contient une instance de la classe Lion. - la classe Lion possède la méthode ami avec comme argument un Animal, héritée de la classe Animal. - l’interpréteur exécute cette méthode.  La surcharge est toujours résolue statiquement par les compilateurs.

28 Exemples en JAVA de conversions des arguments effectifs. (1)
class A { … } class B extends A { … } class Util { static void f (int p, B b) { … } static void f(float x, A a) { … } } A a = new A(); B b = new B(); int n; float x; Util.f(n,b); // ok sans conversions : appel de f(int, B) Util.f(x,a); //ok sans conversions : appel de f(float, A) Util.f(n,a); //conversion de n en float : appel de f(float, A) Util.f(x,b); // conversion de b en A : appel de f(float, A) Uniquement pour simplifier l’exemple

29 Exemples en JAVA de conversions des arguments effectifs. (2)
class A { … } class B extends A { … } class Util { static void f (int p, A a) { … } static void f(float x, B b) { … } } A a = new A (); B b = new B(); int n; float x; Util.f(n,a); // ok sans conversions : appel de f (int, A) Util.f(x,b); //ok sans conversions : appel de f(float, B) Util.f(n,b); // erreur de compilation car ambigu : deux possibilités : // soit convertir n en float et utiliser f(float, B) // soit convertir b en A et utiliser f(int, A) Util.f(x,a); // erreur de compilation : aucune fonction ne convient // (on ne peut pas convertir implicitement de A en B ni // de float en int)

30 Limite de l’héritage et du polymorphisme
La classe Point dispose d’une méthode identique fournissant la valeur true lorsque le point fourni en argument a les mêmes coordonnées que le point courant : Point p1, p2; …. p1.identique(p2) // true si p1 et p2 ont mêmes coordonnées La classe Pointcol, dérivée de Point, redéfinit cette méthode pour prendre en compte Non seulement l’égalité des coordonnées, mais aussi celle de la couleur : Pointcol pc1, pc2; pc1.identique(pc2) // true si pc1 et pc2 ont même coordonnées et même couleur Point p1 = new Pointcol (1,2,(byte)5); Point p2 = new Pointcol (1,2,(byte) 8); p1.identique(p2) true


Télécharger ppt "Le polymorphisme."

Présentations similaires


Annonces Google