Sobes.tech
Senior

Explicați principiul de substituție al lui Barbara Liskov.

sobes.tech AI

Răspuns de la AI

Dacă în program, S este un subtip al T, atunci obiectele de tip T din program pot fi înlocuite cu obiecte de tip S fără a afecta funcționarea programului.

Puncte cheie:

  • Păstrarea comportamentului: Subtipul trebuie să se comporte la fel ca tipul său de bază, din perspectiva observatorului extern.
  • Invarianti: Invariantiile clasei de bază trebuie păstrate în subclase.
  • Postcondiții: Postcondițiile (condițiile care trebuie să fie adevărate după executarea unei metode) subclasei trebuie să fie aceleași sau mai puternice decât cele ale clasei de bază.
  • Precondiții: Precondițiile (condițiile care trebuie să fie adevărate înainte de executarea unei metode) subclasei trebuie să fie aceleași sau mai slabe decât cele ale clasei de bază.

Exemplu în 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 # Încălcare a principiului: schimbarea lățimii schimbă și înălțimea

    def set_height(self, height):
        self._width = height # Încălcare a principiului: schimbarea înălțimii schimbă și lățimea
        self._height = height

# Exemplu de utilizare care încalcă 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"Suprafața după enlarge_rectangle(rect): {enlarge_rectangle(rect)}") # Se așteaptă 12

square = Square(2)
print(f"Suprafața după enlarge_rectangle(square): {enlarge_rectangle(square)}") # Se așteaptă 9, dar din cauza set_width/set_height în Square va fi 16. Încălcare!

Acest principiu este important pentru asigurarea corectitudinii moștenirii și polimorfismului, făcând codul mai fiabil și previzibil.