Sobes.tech
Senior

Expliquez le principe de substitution de Barbara Liskov.

sobes.tech IA

Réponse de l'IA

Si dans un programme, S est un sous-type de T, alors les objets de type T dans le programme peuvent être remplacés par des objets de type S sans violer la fonctionnalité du programme.

Points clés :

  • Conservation du comportement : Le sous-type doit se comporter de la même manière que son type de base, du point de vue de l'observateur externe.
  • Invariants : Les invariants de la classe de base doivent être maintenus dans les sous-classes.
  • Postconditions : Les postconditions (conditions qui doivent être vraies après l'exécution d'une méthode) de la sous-classe doivent être égales ou plus fortes que celles de la classe de base.
  • Préconditions : Les préconditions (conditions qui doivent être vraies avant l'exécution d'une méthode) de la sous-classe doivent être égales ou plus faibles que celles de la classe de base.

Exemple en Python :

class Rectangle:
    def __init__(self, width, height):
        self._width = width
        self._height = height

    def set_width(self, width):
        self._width = width

    def set_height(self, height):
        self._height = height

    def area(self):
        return self._width * self._height

class Square(Rectangle):
    def __init__(self, side):
        super().__init__(side, side)

    def set_width(self, width):
        self._width = width
        self._height = width # Violation du principe : changer la largeur change aussi la hauteur

    def set_height(self, height):
        self._width = height # Violation du principe : changer la hauteur change aussi la largeur
        self._height = height

# Exemple d'utilisation violant le LSP :
def enlarge_rectangle(rectangle):
    rectangle.set_width(rectangle._width + 1)
    rectangle.set_height(rectangle._height + 1)
    return rectangle.area()

rect = Rectangle(2, 3)
print(f"Surface après enlarge_rectangle(rect) : {enlarge_rectangle(rect)}") # Attendu 12

square = Square(2)
print(f"Surface après enlarge_rectangle(square) : {enlarge_rectangle(square)}") # Attendu 9, mais à cause de set_width/set_height dans Square, ce sera 16. Violation !

Ce principe est important pour assurer la correction de l'héritage et du polymorphisme, rendant le code plus fiable et prévisible.