Nous avons vu différents types d'abstraction, et nous allons nous intéresser à l'abstraction par hiérarchie de type, qui est un des piliers des concepts de l'orienté-objet.
En orienté-objet, l'héritage permet par exemple de définir des comportements minimum pour une classe, et d'ajouter les comportements spécifiques dans des classes enfants, qui héritent (dérivent) de la classe parent.
Parmi les avantages de cette manière de programmer, nous pouvons retenir qu'il n'est plus nécessaire de re-définir dans les classes enfants ce qui est déjà défini dans les classes parents. Ceci nous permet une abstraction par hiérarchie de type, c'est à dire que nous pouvons considérer les différents enfants comme étant du type parent.
Un des exemple souvent utilisé pour expliquer l'héritage est issu de la géométrie :
Ce type de classement est tout à fait correct au niveau de la sémantique et selon le point de vue de la géométrie, et naturellement c'est de cette manière que nous construisons notre hiérarchie de classes en programmation.
Cependant, Liskov soulève un problème au niveau du comportement attendu, car notre structure renforce à chaque fois les contraintes nécessaires à la création d'une forme par rapport à sa forme parent.
“Let q(x) be a property provable about objects x of type T. Then q(y) should be true for objects y of type S where S is a subtype of T.”
« Si q(x) est une propriété démontrable pour tout objet x de type T, alors q(y) est vraie pour tout objet y de type S tel que S est un sous-type de T. »Barbara Liskov[2]et Jeannette Wing[3]
La sémantique nous pousse à utiliser une hiérarchie comme nous l'avons vu dans notre exemple du carré qui hérite des propriétés du rectangle, ce qui est logique car un carré est au moins un rectangle.
Cependant, si nous définissons dans la classe rectangle les méthodes suivantes affecteLargeur(entier largeur), affecteHauteur(entier hauteur), et entier donneSurface(), la méthode de calcul de la surface renvera la largeur multipliée par la hauteur. C'est correct.
Selon Liskov, le carré doit pouvoir à tout moment se comporter comme un rectangle. Notre exemple semble fonctionner correctement, voyons un cas pratique...
Que s'est-il passé ? La méthode donne surface s'est comportée exactement de la méme manière pour le carré que pour le rectangle (largeur*hauteur), mais nous violons le principe de substitution de Liskov à chaque fois que nous affectons une valeur pour la largeur ou la hauteur du carré, car cela provoque un résultat différent.
Pourtant nous sommes obligés dans les affectations du carré d'afecter la méme valeur à la largeur et à la hauteur, sinon nous ne respectons plus la sémantique du carré.
Un des moyens de respecter les principes de substitutions de Liskov est d'inverser notre conçeption habituelle de l'héritage, et de coder un rectangle qui hérite d'un carré.
Proposition de solution
Nous pouvons donc utiliser la solution suivante : comme notre carré ne peut pas produire le résultat attendu sur un rectangle, nous ne définirons pas le carré comme héritant du rectangle, mais tous deux sont au même niveau, héritant du quadrilatère.
« Heu... Comment je fais si je veux mettre ensemble les carrés et les rectangles ? »
Comme le carré et le rectangle possèdent des caractéristiques communes que ne partagent pas les autres quadrilatères (4 angles droits), nous pouvons dire que le carré et le rectangle implémentent l'interface "QuatreAnglesDroits".
Par exemple en Java, si nous demandons sur notre objet qui est de type réel carré ou rectangle s'il est une instance de "Quadrilatère", il nous répondra "oui", et de la même manière si nous lui demandons s'il est une instance de "QuatreAnglesDroits" il nous répondra aussi "oui".
L'abstraction par spécifications nous donne quelques pistes pour respecter le principe de substitution de Liskov :
Même si je n'adhère pas toujours aux propos de Barbara Liskov[4], les principes de substitution de Liskov soulèvent certaines questions intéressantes, et nous sensibilisent à certains dangers dans notre pratique de l'orienté-objet.
Nous devons avoir conscience du problème, mais nous utilisons souvent les principes d'héritage sans modifier le comportement des sous-classes, ce qui est sans danger.
Je n'ai pas le temps pour l'instant de détailler plus le sujet, mais il mérite que l'on s'y attarde, et je le ferais par la suite.
Vous pouvez modifier vos préférences dans votre profil pour ne plus afficher les interactions avec les réseaux sociaux sur ces pages.
15 mots clés dont 0 définis manuellement (plus d'information...).
Avertissement
Cette page ne possède pas encore de mots clés manuels, ceci est donc un exemple automatique (les niveaux de pertinence sont fictifs, mais les liens sont valables). Pour tester le nuage avec une page qui contient des mots définis manuellement, vous pouvez cliquer ici.Vous pouvez modifier vos préférences dans votre profil pour ne plus afficher le nuage de mots clés.
Ces références et liens indiquent des documents consultés lors de la rédaction de cette page, ou qui peuvent apporter un complément d'information, mais les auteurs de ces sources ne peuvent être tenus responsables du contenu de cette page.
L'auteur de ce site est seul responsable de la manière dont sont présentés ici les différents concepts, et des libertés qui sont prises avec les ouvrages de référence. N'oubliez pas que vous devez croiser les informations de sources multiples afin de diminuer les risques d'erreurs.
Recherche (afficher)
Utilisateur (masquer)
Navigation (masquer)
Apparence (afficher)
Stats (afficher)
Citation (masquer)