Til: English O’zbek
Liskov Substitution Principle (LSP)
Quyi turlar (subtype’lar) asosiy turlar (base type’lar) o’rnida ishlatilganda dasturning to’g’ri ishlashiga ta’sir qilmasligi kerak.
Agar kod asosiy klass bilan ishlasa, uning istalgan subklassi bilan ham to’g’ri ishlashi shart — kutilmagan xatti-harakatlar bo’lmasligi kerak.
Diagramma
Noto’g’ri yondashuv
violation.py dagi Square klassi Rectangle‘dan meros oladi va setter’larni override qiladi — width va height doimo teng bo’lishi uchun. Bu Rectangle‘ning xatti-harakat shartnomasini buzadi:
class Square(Rectangle):
def set_width(self, width: float) -> None:
self._width = width
self._height = width # kutilmagan nojo'ya ta'sir!
def set_height(self, height: float) -> None:
self._width = height # kutilmagan nojo'ya ta'sir!
self._height = height
Width va height’ni mustaqil ravishda o’rnatadigan har qanday kod Square berilganda noto’g’ri natija beradi:
def resize_rectangle(rect: Rectangle, width: float, height: float) -> float:
rect.set_width(width)
rect.set_height(height)
expected = width * height
actual = rect.area()
assert actual == expected # Square uchun xatolik!
To’g’ri yondashuv
correct.py dagi Rectangle va Square ikkisi ham umumiy Shape abstraktsiyasidan meros oladi. Har bir shakl o’z geometriyasini mustaqil boshqaradi:
class Shape(ABC):
@abstractmethod
def area(self) -> float: ...
class Rectangle(Shape):
def __init__(self, width: float, height: float) -> None:
self.width = width
self.height = height
def area(self) -> float:
return self.width * self.height
class Square(Shape):
def __init__(self, side: float) -> None:
self.side = side
def area(self) -> float:
return self.side ** 2
Ikkalasi ham Shape kutilgan joyda ishlatilishi mumkin — kutilmagan xatti-harakatlarsiz.