Sobes.tech
Senior

Обяснете принципа на заместване на Барбара Лисков.

sobes.tech AI

Отговор от AI

Ако в програма S е подтип на T, тогава обектите от тип T в програмата могат да бъдат заменени с обекти от тип S без нарушаване на функционалността на програмата.

Ключови моменти:

  • Запазване на поведението: Подтипът трябва да се държи по същия начин като базовия тип, от гледна точка на външния наблюдател.
  • Инварианти: Инвариантите на базовия клас трябва да се запазват в подкласовете.
  • Постусловия: Постусловията (условията, които трябва да са верни след изпълнение на метода) на подкласовете трябва да са същите или по-силни от тези на базовия клас.
  • Предусловия: Предусловията (условията, които трябва да са верни преди изпълнение на метода) на подкласовете трябва да са същите или по-слаби от тези на базовия клас.

Пример на 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 # Нарушение на принципа: промяната на ширината променя и височината

    def set_height(self, height):
        self._width = height # Нарушение на принципа: промяната на височината променя и ширината
        self._height = height

# Пример за използване, който нарушава 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"Площ след enlarge_rectangle(rect): {enlarge_rectangle(rect)}") # Очаква се 12

square = Square(2)
print(f"Площ след enlarge_rectangle(square): {enlarge_rectangle(square)}") # Очаква се 9, но поради set_width/set_height в Square ще бъде 16. Нарушение!

Този принцип е важен за гарантиране на коректността на наследяването и полиморфизма, като прави кода по-надежден и предсказуем.