1
resposta

Hora da prática: instância de uma classe

arquivo classes.py

class Veiculo:
    def __init__(self, marca, modelo):
        self.marca = marca
        self.modelo = modelo
        self._ligado = False

    def __str__(self):
        return f"Marca: {self.marca} | Modelo: {self.modelo} | Estado: {"Ligado" if self._ligado else "Desligado"}"
    

class Carro(Veiculo):
    def __init__(self, marca, modelo, portas):
        super().__init__(marca, modelo)
        self.portas = portas

    def __str__(self):
        return f"{super().__str__()} | Portas: {self.portas}"
    

class Moto(Veiculo):
    def __init__(self, marca, modelo, tipo):
        super().__init__(marca, modelo)
        self.tipo = tipo

    def __str__(self):
        return f"{super().__str__()} | Tipo: {self.tipo}"
    
      

arquivo main.py

from classes import Veiculo, Moto, Carro

carro1 = Carro("Fiat", "Uno", 4)
carro2 = Carro("Volkswagen", "Gol", 4)
carro3 = Carro("Chevrolet", "Onix", 4)

moto1 = Moto("Honda", "CB500", "Esportiva")
moto2 = Moto("Yamaha", "MT-07", "Casual")
moto3 = Moto("Kawasaki", "Ninja 400", "Esportiva")

print(carro1)
print(carro2)
print(carro3)
print(moto1)
print(moto2)
print(moto3)
1 resposta

Olá, Luiz Fernando. Como vai?

Parabéns pela resolução da atividade! Seu código está excelente e demonstra que você compreendeu perfeitamente os pilares de Herança e Polimorfismo na Orientação a Objetos com Python.

A estrutura do seu arquivo classes.py ficou muito bem desenhada:

  • Uso correto do super().__init__(): Essencial para garantir que os atributos da classe mãe (Veiculo) sejam inicializados corretamente no momento em que um Carro ou uma Moto nascem.
  • Sobrescrita do método __str__: Você utilizou uma das melhores práticas de POO ao chamar o super().__str__() dentro das classes filhas. Isso evita a repetição de código, aproveitando a string base de marca, modelo e estado, adicionando apenas a especialização de cada um (portas ou tipo).

Há apenas um detalhe técnico sutil de sintaxe e indentação no seu arquivo classes.py que fará com que o código lance um erro na hora de rodar. Vamos analisar juntos:

1. Aspas aninhadas no método __str__ de Veiculo

Na linha 8, você construiu a f-string usando aspas duplas por fora e também aspas duplas por dentro no operador ternário:

return f"Marca: {self.marca} | Modelo: {self.modelo} | Estado: {"Ligado" if self._ligado else "Desligado"}"

Quando o Python vê isso, ele se confunde e acha que a string fecha logo antes da palavra Ligado. Para corrigir isso, a regra de ouro é: se usar aspas duplas por fora da f-string, use aspas simples por dentro (ou vice-versa):

return f"Marca: {self.marca} | Modelo: {self.modelo} | Estado: {'Ligado' if self._ligado else 'Desligado'}"

2. Indentação das Classes Filhas

No seu bloco de código, as declarações class Carro(Veiculo): e class Moto(Veiculo): aparecem deslocadas para a direita, como se estivessem "dentro" da classe Veiculo. No Python, as classes precisam ficar no mesmo nível de recuo (alinhadas à esquerda na margem do arquivo).

Para visualizar perfeitamente como essa estrutura de herança organiza os objetos e seus respectivos atributos na memória do Python, veja o esquema abaixo:

Como deve ficar o seu arquivo classes.py corrigido:

class Veiculo:
    def __init__(self, marca, modelo):
        self.marca = marca
        self.modelo = modelo
        self._ligado = False

    def __str__(self):
        # Corrigido: aspas simples por dentro do operador ternário
        return f"Marca: {self.marca} | Modelo: {self.modelo} | Estado: {'Ligado' if self._ligado else 'Desligado'}"

# Corrigido: classe Carro alinhada na margem esquerda
class Carro(Veiculo):
    def __init__(self, marca, modelo, portas):
        super().__init__(marca, modelo)
        self.portas = portas

    def __str__(self):
        return f"{super().__str__()} | Portas: {self.portas}"

# Corrigido: classe Moto alinhada na margem esquerda
class Moto(Veiculo):
    def __init__(self, marca, modelo, tipo):
        super().__init__(marca, modelo)
        self.tipo = tipo

    def __str__(self):
        return f"{super().__str__()} | Tipo: {self.tipo}"

O seu arquivo main.py está impecável, criando as instâncias com os argumentos corretos e fazendo os prints de forma limpa. Realizando esse pequeno ajuste de formatação nas classes, seu programa rodará perfeitamente. Excelente trabalho!

Espero que possa ter lhe ajudado!