Entendendo Herança em Python

Herança

A herança permite que uma classe herde atributos e métodos de outra classe, facilitando a reutilização.

Exemplo: Veículo

Um clássico exemplo seria o exemplo de Veículo.

Vamos supor que vamos construir um cadastro de veículos, então podemos:

  • Cadastrar uma moto
  • Cadastrar um carro
  • Cadastrar uma bicicleta

Ok, então para não criar uma classe do zero Carro, Moto e Bicicleta, podemos encontrar atributos e métodos em comum para poder reaproveitar o código.

Atributos em comum

Quais atributos tanto um carro, quanto uma moto e uma bicicleta possuem em comum?

  • Quantidade de rodas
  • Marca
  • Modelo

Métodos em comum

  • Acelerar (no caso da bicicleta seria pedalar, mas tudo bem)
  • Frear
  • Mudar Direção

Criando a classe que será herdada

Então como temos métodos e atributos em comum, podemos criar uma classe que possua esses atributos/métodos para ser reaproveitado por outras classes.

Podemos dar o nome dessa classe de Veiculo.

class Veiculo:

    def __init__(self, marca: str, modelo: str, qtd_rodas: int):
        self.marca = marca
        self.modelo = modelo
        self.qtd_rodas = qtd_rodas

    def acelerar(self):
        print("acelerar!")

    def frear(self):
        print("frear!")

    def mudar_direcao(self, direcao: str):
        print(f"Mudando direção para: {direcao}")

Aplicando Herança

Beleza, agora podemos aplicar o conceito de herança através dessa classe Veiculo.
Vamos criar a classe Carro, herdando a classe Veiculo e reaproveitando os métodos e atributos existentes.

Atenção
Quando herdamos uma classe, não nos limitamos aos métodos e atributos dela. Nossas subclasses podem ter atributos e métodos específicos. A proposta da herança é reaproveitar métodos e atributos em comum.

Carro

Vamos herdar a classe Veiculo na classe Carro, definir os atributos essenciais para o Veiculo e algum atributo exclusivo do carro. Além disso, vamos construir um método que só o carro tem também.

class Carro(Veiculo):

    def __init__(self, marca: str, modelo: str, qtd_rodas: int, tipo_combustivel: str):

        """
            Usamos o `super()` para acessar a classe superior (Veiculo)
            E passamos no construtor os atributos necessarios.
        """
        super().__init__(marca, modelo, qtd_rodas)

        # exemplo de um atributo exclusivo do carro
        self.tipo_combustivel = tipo_combustivel

    def ligar_radio(self):
        """ Exemplo de um método exclusivo do carro """

        print("Radio ligado")

Usando a classe Carro

camaro = Carro(
    marca='Chevrolet', 
    modelo='Camaro SS', 
    qtd_rodas=4, 
    tipo_combustivel='Gasolina'
)

# reaproveitando o método da classe Veiculo
camaro.acelerar()
camaro.frear()
camaro.mudar_direcao('esquerda')

# usando o metodo exclusivo da classe Carro
camaro.ligar_radio()

Saída

acelerar!
frear!
Mudando direção para: esquerda
Radio ligado

Conclusão e outros exemplos

Não vou implementar a classe Moto e Bicicleta se não fica muito grande o conteúdo, e a ideia é a mesma:

  • Vamos herdar Veiculo
  • Receber no construtor os atributos necessários para o Veiculo e atributos/métodos específicos da subclasse
  • Ao instanciar a classe, podemos usar tanto os métodos/atributos do Veiculo quanto os específicos da subclasse

Então vou deixar alguns exemplos onde podemos aplicar Herança em sistemas mais tradicionais.

Sistema de Bancos

Classe Conta com atributos básicos; subclasses ContaCorrente, ContaPoupanca, ContaInvestimento com características específicas.

Gestão de Clientes

Classe Pessoa para dados gerais; subclasses ClienteIndividual, ClienteEmpresarial para detalhes específicos.

Sistema Escolar

Classe MembroEscola para informações comuns; subclasses Estudante, Professor, Administrativo para funções específicas.

Sistema de Reservas

Classe Reserva com atributos gerais; subclasses ReservaHotel, ReservaVoo, ReservaRestaurante com detalhes específicos.

Loja de Roupas Online

Classe Produto para informações básicas; subclasses Camisa, Calca, Acessorio para categorias de produtos.

Sistema Imobiliário

Classe Imovel para atributos gerais; subclasses Casa, Apartamento, Comercial para diferentes tipos de propriedades.

Se aprofundando…

Vou deixar uma apostila da Caelum sobre Programação Orientada a Objetos para Python.
Bem completa, tem herança, polimorfismo, explica detalhes das classes em Python, etc.