Olá Roger, tudo bem?
Vamos supor um exemplo onde eu tenho uma classe Retangulo
, essa classe só possui dois parâmetros, a base e a altura:
class Retangulo:
def __init__(self, base, altura):
self.base = base
self.altura = altura
def get_lados():
return base, altura
Agora vamos pegar uma classe Quadrado
que estende de Retangulo
.
class Quadrado(Retangulo):
def __init__(self, lado):
self.lado = lado
def get_lados():
return lado
Esta classe, apesar de estender Retangulo
possui algumas diferenças. Por exemplo, o retângulo permite que seus lados tenham medidas diferentes, já o quadrado não.
Apesar de Quadrado
estender Retângulo
, ele limita algumas ações que podemos fazer com o triângulo.
Por exemplo, se temos uma variável que recebe o retorno de get_lados()
. Devemos tratar o retorno dessa variável como um retorno vindo de um quadrado ou de um retângulo?
Ou ainda, em algum momento no código eu deva criar um quadrado, mas o valor dos lados são diferentes, logo não podemos criá-lo.
O Quadrado
é um Retangulo
. Ambos são quadriláteros. Porém, se em algum momento do código esperamos o retorno de um Retangulo
, como no caso do get_lado
, receber o retorno da classe Quadrado
pode causar uma reação inesperada no código.
Como o Python é dinamicamente tipado, efeitos colaterais são mais fáceis de serem resolvidos, mas em linguagens com tipagem estática, esse problema é mais corrente.
Esse tipo de análise é conhecido como Princípio de Substituição de Liskov. Esse princípio é uma das letras do SOLID.