Sobes.tech
Senior

Explique o princípio de substituição de Barbara Liskov.

sobes.tech IA

Resposta da IA

Se num programa, S é um subtipo de T, então os objetos de tipo T no programa podem ser substituídos por objetos de tipo S sem violar a funcionalidade do programa.

Pontos-chave:

  • Manutenção do comportamento: O subtipo deve comportar-se da mesma forma que seu tipo base, do ponto de vista do observador externo.
  • Invariantes: Os invariantes da classe base devem ser mantidos nas subclasses.
  • Pós-condições: As pós-condições (condições que devem ser verdadeiras após a execução de um método) da subclasse devem ser iguais ou mais fortes que as da classe base.
  • Pré-condições: As pré-condições (condições que devem ser verdadeiras antes de executar um método) da subclasse devem ser iguais ou mais fracas que as da classe base.

Exemplo em 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 # Violação do princípio: mudar a largura também muda a altura

    def set_height(self, height):
        self._width = height # Violação do princípio: mudar a altura também muda a largura
        self._height = height

# Exemplo de uso que viola o 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"Área após enlarge_rectangle(rect): {enlarge_rectangle(rect)}") # Espera-se 12

square = Square(2)
print(f"Área após enlarge_rectangle(square): {enlarge_rectangle(square)}") # Espera-se 9, mas devido a set_width/set_height em Square, será 16. Violação!

Este princípio é importante para garantir a correção na herança e no polimorfismo, tornando o código mais confiável e previsível.