DEV Community

Giovanne Barbosa
Giovanne Barbosa

Posted on

SOLID - LSP

Princípio da substituição de Liskov

Se q(x) é uma propriedade demonstrável dos objetos x de tipo T. Então q(y) deve ser verdadeiro para objetos y de tipo S onde S é um subtipo de T.

Se a nossa classe não pode se comportar como a classe que ela está herdando, então temos um problema de abstração.

Por exemplo:

Temos uma classe Veículo, com um método voar() e temos uma classe Helicóptero que herda essa classe Veículo.

    public class Veiculo
    {
        public string Nome { get; set; }
        public virtual void Voar()
        {
            Console.WriteLine($"O veículo {Nome} está voando");
        }
    }

    public class Helicoptero : Veiculo
    {

    }
Enter fullscreen mode Exit fullscreen mode

Tudo certo, afinal um helicóptero é um subtipo de veículo e o helicóptero pode voar. Mas e se tivermos uma classe Moto herdando a classe Veículo, desta forma?

    public class Moto: Veiculo
    {

    }

...

Veiculo moto = new Moto();
moto.Voar() //>>>>>>>>>> WTF!?

Enter fullscreen mode Exit fullscreen mode

Uma moto é um veículo, porém não pode voar. Logo, estamos quebrando o princípio da substituição de Liskov.

Solução:

Tiramos o método voar() da classe Veículo e criamos uma classe VeículoAéreo com o método voar() e então fazemos com que nossa classe Helicóptero herde a classe VeículoAéreo.

    public class Veiculo
    {
        public string Nome { get; set; }
    }

    public class VeiculoAereo : Veiculo
    {
        public virtual void Voar()
        {
            Console.WriteLine($"O veículo {Nome} está voando");
        }
    }

    public class Helicoptero : VeiculoAereo
    {

    }

    public class Moto: Veiculo
    {

    }
Enter fullscreen mode Exit fullscreen mode

Desta forma nem a moto e nem o helicóptero deixam de ser um veiculo, porem não é mais possível voar com a moto (nunca foi).

Criei uma classe LavaRapido com um método Lavar() que recebe um tipo de Veiculo

    public class LavaRapido
    {
        public void Lavar(Veiculo veiculo)
        {
            Console.WriteLine($"Lavando o veiculo {veiculo.Nome}");
        }
    }
Enter fullscreen mode Exit fullscreen mode

E assim consigo lavar meus dois veículos, mesmo que o helicóptero seja um veículo aéreo, pois a classe VeiculoAereo ainda é um subtipo de Veiculo.

var lavaRapido = new LavaRapido();

Veiculo moto = new Moto();
VeiculoAereo helicoptero = new Helicoptero();

lavaRapido.Lavar(moto);
lavaRapido.Lavar(helicoptero);
Enter fullscreen mode Exit fullscreen mode

Discussion (0)