Sobes.tech
Senior

Leg het substitutieprincipe van Barbara Liskov uit.

sobes.tech AI

Antwoord van AI

Als in een programma S een subtype is van T, dan kunnen objecten van type T in het programma worden vervangen door objecten van type S zonder de functionaliteit van het programma te schaden.

Belangrijke punten:

  • Gedragsbehoud: Het subtype moet zich gedragen zoals het basistype, vanuit het oogpunt van de externe waarnemer.
  • Invarianten: De invarianten van de basisklasse moeten worden behouden in de subklassen.
  • Postcondities: De postcondities (voorwaarden die waar moeten zijn na het uitvoeren van een methode) van de subklasse moeten gelijk of sterker zijn dan die van de basisklasse.
  • Precondities: De precondities (voorwaarden die waar moeten zijn voordat een methode wordt uitgevoerd) van de subklasse moeten gelijk of zwakker zijn dan die van de basisklasse.

Voorbeeld in 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 # Schending van het principe: het wijzigen van de breedte wijzigt ook de hoogte

    def set_height(self, height):
        self._width = height # Schending van het principe: het wijzigen van de hoogte wijzigt ook de breedte
        self._height = height

# Voorbeeld van gebruik dat LSP schendt:
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"Oppervlakte na enlarge_rectangle(rect): {enlarge_rectangle(rect)}") # Verwacht 12

square = Square(2)
print(f"Oppervlakte na enlarge_rectangle(square): {enlarge_rectangle(square)}") # Verwacht 9, maar door set_width/set_height in Square wordt het 16. Schending!

Dit principe is belangrijk om de correctheid van erfelijkheid en polymorfisme te waarborgen, waardoor de code betrouwbaarder en voorspelbaarder wordt.