Sobes.tech
Senior

Erklären Sie das Substitutionsprinzip von Barbara Liskov.

sobes.tech KI

Antwort von AI

Wenn in einem Programm S ein Untertyp von T ist, können Objekte vom Typ T im Programm durch Objekte vom Typ S ersetzt werden, ohne die Funktionalität des Programms zu verletzen.

Wichtige Punkte:

  • Verhaltenskonservierung: Der Untertyp sollte sich so verhalten wie sein Basistyp, aus der Sicht des externen Beobachters.
  • Invarianten: Die Invarianten der Basisklasse sollten in den Unterklassen erhalten bleiben.
  • Postbedingungen: Die Postbedingungen (Bedingungen, die nach der Ausführung einer Methode wahr sein müssen) der Unterklasse sollten gleich oder stärker sein als die der Basisklasse.
  • Preconditions: Die Preconditions (Bedingungen, die vor der Ausführung einer Methode wahr sein müssen) der Unterklasse sollten gleich oder schwächer sein als die der Basisklasse.

Beispiel 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 # Verletzung des Prinzips: Änderung der Breite ändert auch die Höhe

    def set_height(self, height):
        self._width = height # Verletzung des Prinzips: Änderung der Höhe ändert auch die Breite
        self._height = height

# Beispiel für die Verwendung, die LSP verletzt:
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"Fläche nach enlarge_rectangle(rect): {enlarge_rectangle(rect)}") # Erwartet 12

square = Square(2)
print(f"Fläche nach enlarge_rectangle(square): {enlarge_rectangle(square)}") # Erwartet 9, aber aufgrund von set_width/set_height in Square wird es 16. Verletzung!

Dieses Prinzip ist wichtig, um die Korrektheit von Vererbung und Polymorphismus zu gewährleisten und den Code zuverlässiger und vorhersehbarer zu machen.