Categorias do Site

Princípio de Substituição de Liskov: Guia Completo

Descubra o Princípio de Substituição de Liskov e como ele garante a robustez e flexibilidade do código em design orientado a objetos.

Cubo tridimensional com texturas de fumaça em tons de roxo, azul e rosa, contendo as letras

Os princípios SOLID são considerados regras de ouro para criar um código robusto e flexível. Criados pelo renomado Robert C. Martin, eles são fundamentais para um design orientado a objetos limpo e sustentável:

  1. Princípio da Responsabilidade Única (SRP)
  2. Princípio Aberto/Fechado (OCP)
  3. Princípio de Substituição de Liskov (LSP)
  4. Princípio da Segregação de Interfaces (ISP)
  5. Princípio da Inversão de Dependência (DIP)

O Princípio de Substituição de Liskov (LSP) é o herói desconhecido que garante que substituir um objeto por outro não quebre seu sistema. Ele reforça a estrutura lógica e a confiabilidade em seu código:

O que é o LSP?

Nomeado em homenagem à cientista da computação Barbara Liskov, este princípio é baseado na ideia de que você deve poder substituir uma classe pai por uma de suas subclasses sem quebrar seu código.

Por exemplo, um software projetado para carros autônomos deve funcionar com qualquer veículo. Se funcionar bem com um carro, mas falhar com um caminhão, o LSP foi violado. O código confiou demais no pai e não considerou o comportamento dos filhos.

Por que o LSP é importante?

O LSP é essencial para a extensão dos sistemas. Um sistema que segue o LSP oferece:

  • Sem falhas inesperadas – A troca de subclasses não quebra o programa, pois são consistentes com a superclasse.
  • Expansão sem medo – LSP garante que novos elementos se integrem sem problemas adicionais.
  • Correção facilitada – Permite ajustes sem reescrever todo o código.
  • Testes simplificados – Comportamentos consistentes tornam os testes mais fáceis.

Substituir subclasses sem quebrar o código

No cerne do LSP está a confiança. Você deve substituir uma classe pai por uma classe filha e esperar que tudo funcione bem. Uma subclasse não deve exigir mais do que a classe pai ou entregar menos do que prometido.

Pré-condições

São as condições que devem ser verdadeiras antes de um método ser executado. Uma subclasse não deve exigir mais do que a superclasse.

Pós-condições

São os resultados garantidos após a execução de um método. A subclasse não deve entregar menos do que a superclasse prometeu.

Entendendo o LSP com uma analogia do mundo real

Parece lógico dizer que um quadrado é um retângulo com lados iguais, certo? No entanto, ao tratar o quadrado como subclasse de um retângulo, violamos o LSP. A classe Quadrado que impõe lados iguais não pode substituir de forma confiável uma classe Retângulo que pressupõe largura e altura independentes.

Violações do LSP: O que dá errado e como corrigir

Mesmo compreendendo o LSP, é fácil violá-lo. A violação pode surgir quando a subclasse altera um comportamento prometido pela superclasse, causando exceções inesperadas.

Problema do quadrado-retângulo: Quando a subclasse leva a comportamentos incorretos

Ao forçar uma relação de herança onde o comportamento diverge, é melhor manter entidades separadas, permitindo que existam como formas independentes que compartilham características em comum.

Métodos lançando exceções inesperadas

O LSP é frequentemente violado quando uma subclasse remove ou altera um comportamento prometido pela superclasse, resultando em exceções inesperadas.

Valores de retorno inesperados

Outra violação comum do LSP ocorre quando uma subclasse retorna algo inesperado, que o sistema não está preparado para lidar.

LSP em diferentes linguagens de programação

Independentemente da linguagem de programação, a ideia central do Liskov Substitution Principle (LSP) permanece a mesma: subclasses devem ser substitutos confiáveis para suas superclasses.

LSP em Python

No Python, a tipagem dinâmica e o duck typing exigem cuidado para garantir que a subclasse se comporte como a superclasse.

from abc import ABC, abstractmethod

class Bird(ABC):
   @abstractmethod
   def fly(self) -> None:
       pass

class Sparrow(Bird):
   def fly(self) -> None:
       print("Sparrow flying")  # satisfaz o contrato
# Código cliente
def let_it_fly(b: Bird):
   b.fly()

Programando para uma base abstrata, qualquer subclasse que suporte fly() pode ser usada de forma intercambiável.

LSP em Java

Java, com seu sistema de tipos estáticos, reforça a necessidade do LSP, garantindo que subclasses possam se integrar sem comprometer a estrutura.

interface Shape {
   double area();
}
class Circle implements Shape {
   private final double radius;
   public Circle(double r) { radius = r; }
   public double area() { return Math.PI * radius * radius; }
}

Qualquer subclasse que implemente area() deve respeitar o contrato original, sem efeitos colaterais inesperados, e o resultado deve ser sempre um valor positivo.

LSP em TypeScript

Em TypeScript, a tipagem estática garante que subclasses mantenham assinaturas de método consistentes.

interface ButtonProps { onClick: () => void; label: string; }


function PrimaryButton(props: ButtonProps) {
   return ;
}


function IconButton(props: ButtonProps & { icon: string }) {
   return ;
}

IconButton estende os props sem remover ou alterar nenhum dos campos obrigatórios.

LSP em C#

O C# utiliza classes abstratas e interfaces para garantir ordem e estrutura, mantendo a consistência de comportamento.

public interface IRepository {
   T GetById(int id);
}
public class SqlRepository : IRepository {
   public T GetById(int id) {
       // buscar no banco de dados SQL
   }
}

Os repositórios concretos devem cumprir garantias em torno de retornos não nulos e tratamento adequado de exceções.

LSP no desenvolvimento de software moderno

O Princípio de Substituição de Liskov continua a ser valioso em sistemas modernos, garantindo que arquiteturas complexas funcionem de forma confiável.

LSP em programação funcional e injeção de dependência

No contexto de injeção de dependência e programação funcional, o LSP garante que funções ou serviços substituíveis não introduzam surpresas comportamentais inesperadas.

LSP em componentes React e serviços Angular

Ao projetar componentes React, o LSP garante que o comportamento esperado seja mantido consistentemente. Em Angular, o princípio assegura a consistência e previsibilidade dos serviços.

Angular services:
@Injectable({ providedIn: 'root' })
export abstract class AuthService {
   abstract login(credentials: Credential): Observable;
}


@Injectable()
export class RealAuthService extends AuthService {
   login(c: Credential) { /* chamada http */ }
}

Os clientes devem poder alternar entre implementações simuladas e reais sem alterar o comportamento esperado.

LSP em arquiteturas de microsserviços

No contexto de microsserviços, o LSP é crucial para manter a compatibilidade de APIs à medida que os serviços evoluem, garantindo transições suaves entre diferentes versões de serviço.

Comparando LSP com outros princípios SOLID

O LSP tem uma relação importante com outros princípios SOLID. Ele atua como guardião, garantindo que o sistema permaneça seguro e estável à medida que cresce.

Melhores práticas para implementar o Princípio de Substituição de Liskov

Recomendações para aplicar o LSP efetivamente:

Refatorar com confiança: Lidando com violações do LSP

Diretrizes para refatorar código que viola o LSP:

  • Se as subclasses não se comportam como esperado, o problema pode estar em uma classe base muito ativa. Aplique a segregação de interfaces para definir contratos menores e mais focados.
  • Considere usar delegação ou composição para compartilhar comportamento de forma mais segura e flexível.
  • Quando possível, mova o comportamento para classes de estratégia que possam ser injetadas, em vez de substituídas, mantendo as responsabilidades claras e evitando quebrar o contrato do pai.

Testando o LSP: Como garantir que as subclasses se comportem corretamente

Para estruturar testes que sigam o LSP:

  • Escreva testes que validem o comportamento esperado da superclasse.
  • Execute os mesmos testes em todas as subclasses.
  • Verifique se cada subclasse lida com entradas conforme esperado.
  • Confirme que os resultados permanecem consistentes com o que a superclasse promete.

Essa abordagem ajuda a garantir que suas subclasses realmente se comportem como substituições diretas.

A herança nem sempre é a resposta: Tente composição em vez disso

O LSP é frequentemente violado quando a herança é usada de forma inadequada. Muitas vezes, a composição, que constrói comportamento combinando partes menores e focadas, pode ser uma alternativa mais limpa e confiável.

Considerações finais sobre o Princípio de Substituição de Liskov

O Liskov Substitution Principle (LSP) é essencial para a escrita de código que funciona. Ele garante que as subclasses possam substituir suas superclasses sem causar problemas inesperados.

Claro, o LSP não está sozinho. Ele funciona em conjunto com outros princípios SOLID, como SRP e OCP, ajudando na construção de aplicativos modulares, escaláveis e fáceis de testar.

Como regra geral: se sua subclasse pode substituir sua superclasse sem quebrar nada, você está no caminho certo com o LSP.

  • AI e a Importância da Autopercepção na Comunicação

    Exploramos como a autopercepção influencia a comunicação humano-AI, destacando falhas nos modelos tradicionais de alinhamento.

    Exploramos como a autopercepção influencia a comunicação humano-AI, destacando falhas nos modelos tradicionais de alinhamento.

    Ler notícia completa
    Pessoa segurando um quadro transparente com texto sobre IA contra um céu azul com nuvens.
  • Redesign de UX aumenta resgates em mais de 58%

    Descubra como um redesign de UX elevou a taxa de sucesso de resgates de 60% para 95%, melhorando a confiança e satisfação dos usuários.

    Descubra como um redesign de UX elevou a taxa de sucesso de resgates de 60% para 95%, melhorando a confiança e satisfação dos usuários.

    Ler notícia completa
    Imagem ilustrativa de uma interface de página da web estilizada em tons de roxo e rosa, destacando ícones de design e codificação sobre fundo suave.
  • Introdução aos Runtimes de Agentes de IA

    Descubra o que são runtimes de agentes de IA e como eles impulsionam soluções empresariais eficazes.

    Descubra o que são runtimes de agentes de IA e como eles impulsionam soluções empresariais eficazes.

    Ler notícia completa
    Imagem dividida em duas partes: à esquerda, canteiro de obras com guindaste e materiais de construção; à direita, prédio moderno ao pôr do sol com estrada curva.
  • Guia de Runtimes de Agentes de IA: Escolha o Certo

    No mundo em rápida evolução da inteligência artificial, os agentes de IA estão transformando a operação dos negócios. Esses sistemas inteligentes podem executar tarefas autonomamente, tomar decisões e interagir com usuários — desde simples chatbots até fluxos de trabalho complexos de múltiplos agentes que lidam com análise de dados, atendimento ao cliente ou mesmo desenvolvimento […]

    Descubra como escolher o melhor runtime de agentes de IA para sua empresa em 2025 com comparações e recomendações.

    Ler notícia completa
    Ilustração estilizada dividida em três partes com cores vivas mostrando, da esquerda para a direita, um rosto com olhos grandes e um laptop, um perfil humano com um chip no cérebro, e um gráfico de barras com setas.
  • Deno 2.4: Novidades e Expectativas

    Deno 2.4 destaca-se na evolução do ambiente. Embora o número da versão possa parecer menor, os recursos incorporados representam um grande avanço em direção à maturidade, experiência do desenvolvedor e prontidão para produção. Esta não é apenas uma atualização de manutenção; é uma declaração de intenções. No passado, as discussões sobre Deno frequentemente abordavam suas […]

    Confira as principais novidades do Deno 2.4, incluindo melhorias na compatibilidade com Node.js e novas ferramentas.

    Ler notícia completa
    Logotipo em preto de um pato estilizado dentro de um círculo, sobre um fundo abstrato com textura de pinceladas em tons de rosa e bege.
  • O Significado de Alinhamento em IA

    Introdução Como ex-professor de inglês que entrou na pesquisa de IA, percebo como termos comuns são redefinidos em campos técnicos, como ‘alinhamento’ em IA, que reflete um imperativo ético crucial. O que realmente significa alinhamento O dicionário Cambridge define alinhamento como: ‘um arranjo em que duas ou mais coisas estão posicionadas em linha reta ou […]

    Explore como o conceito de alinhamento em IA evolui para um processo dinâmico e relacional, além de simples salvaguardas.

    Ler notícia completa
    Imagem gráfica de formas onduladas azuis e brancas em um fundo verde-azulado com texto sobre alinhamento de IA, destacando a relação entre humanos e máquinas.
  • Os 15 melhores servidores MCP para projetos de IA

    O Model Context Protocol (MCP) está se tornando rapidamente o padrão para conectar modelos de IA a ferramentas e dados externos. Já adotado por plataformas como VS Code e Claude Desktop, os servidores MCP alimentam desde o acesso a sistemas de arquivos e integrações de API até consultas a bancos de dados e fluxos de […]

    Descubra os 15 principais servidores MCP para otimizar seus projetos de inteligência artificial.

    Ler notícia completa
    Logotipos do Figma, Docker e GitHub sobre fundo colorido em degradê azul e laranja.
  • 40 Ações e Efeitos Gratuitos para Photoshop

    Designers, fotógrafos e artistas digitais passam muitas horas trabalhando no Photoshop, seja projetando, editando fotos ou criando arte digital. Como profissional nessas áreas, você pode receber fotos de clientes que precisam de retoques ou ter que editar suas próprias fotografias. Em ambos os casos, as ações do Photoshop podem ser extremamente úteis para agilizar tarefas […]

    Descubra mais de 40 ações gratuitas para Photoshop em 2025. Transforme suas fotos com efeitos incríveis em poucos cliques.

    Ler notícia completa
    Imagem estilizada em tons de cinza de uma pessoa com moletom e touca, olhando para cima. Há texto e gráficos vermelhos e azuis sobrepostos em estilo glitch. Logo do Photoshop no canto.
  • Design Web Não-Linear: Futuro da Experiência do Usuário

    No mundo em constante evolução do design web, o design linear não é mais suficiente. Como designers, somos desafiados a criar experiências mais dinâmicas, envolventes e intuitivas do que nunca. Surge o design web não-linear, um conceito que vai além da abordagem tradicional de “isso, depois aquilo”. Mas o que exatamente significa design web não-linear […]

    Descubra como o design web não-linear está revolucionando a experiência do usuário e trazendo mais dinamismo e interatividade.

    Ler notícia completa
    Mãos de pessoas trabalhando com esboços de interfaces de usuário, marcadores e um smartphone sobre a mesa.