Construir un sistema de concesionaria en Python permite entender cómo la herencia y el polimorfismo trabajan juntos para crear código reutilizable y organizado. A partir de una superclase Vehiculo, se extienden clases hija como Bicicleta, Auto y Camion, cada una con comportamientos propios, mientras que las clases Comprador y Concesionaria orquestan la lógica de negocio interactuando únicamente con la clase padre.
¿Cómo se crean las clases hija bicicleta y camión?
La clase Bicicleta hereda de Vehiculo y reutiliza todos los parámetros definidos en la superclase [01:08]. Sin embargo, sus métodos reflejan un comportamiento diferente: al no tener motor, los mensajes cambian a "la bicicleta está en marcha" y "la bicicleta se ha detenido", en lugar de hacer referencia a un motor.
Este es un ejemplo claro de sobrescritura de métodos (method overriding): la clase hija redefine funciones heredadas para adaptar su comportamiento sin modificar la clase padre.
python
class Bicicleta(Vehiculo):
def iniciar(self):
print("La bicicleta está en marcha")
def detener(self):print("La bicicleta se ha detenido")
Por otro lado, la clase Camion también hereda de Vehiculo, pero conserva la referencia al motor [02:25], ya que tanto el auto como el camión comparten esa característica.
python
class Camion(Vehiculo):
def iniciar(self):
print("El motor del camión está en marcha")
def detener(self):print("El motor del camión se ha detenido")
Aquí se evidencia el polimorfismo: el mismo método (iniciar, detener) se comporta de forma distinta según la clase que lo implemente.
¿Qué hace la clase comprador y cómo interactúa con los vehículos?
La clase Comprador no hereda de ninguna otra clase [03:15]. Su constructor recibe únicamente un nombre y crea una lista vacía donde se almacenarán los vehículos adquiridos.
python
class Comprador:
def init(self, nombre):
self.name = nombre
self.autos = []
¿Cómo funciona el método comprar vehículo?
El método comprar_vehiculo recibe un objeto de tipo Vehiculo [03:50]. Antes de concretar la compra, consulta si el vehículo está disponible mediante un método del propio objeto. Si lo está, ejecuta vender() sobre el vehículo y lo añade a la colección del comprador. En caso contrario, muestra un mensaje indicando que la marca no está disponible [05:00].
Se verifica disponibilidad con vehiculo.esta_disponible().
Se ejecuta vehiculo.vender() para cambiar el estado.
Se agrega el objeto a la lista self.autos.
¿Cómo se consulta la disponibilidad?
Otro método permite consultar el estado de un vehículo [05:30]. Si está disponible, la variable de estado se establece como "disponible"; si no, como "no disponible". Luego se imprime la marca, el estado y el precio usando get_price() [06:30].
Este diseño demuestra la encapsulación: el comprador no accede directamente a los atributos internos del vehículo, sino que utiliza métodos públicos para interactuar con él.
¿Cómo se estructura la clase concesionaria?
La clase Concesionaria (dealership) maneja dos colecciones principales [07:05]:
El método para añadir vehículos recibe un objeto de tipo Vehiculo, lo agrega al inventario y confirma con un mensaje que incluye la marca [07:50]. De forma similar, el método para registrar clientes recibe un objeto Comprador y lo añade a la lista de customers [08:30].
Por último, el método mostrar_disponibles recorre el inventario con un for y filtra únicamente los vehículos cuyo método esta_disponible() devuelva verdadero [09:20]. Para cada uno imprime la marca y el precio.
python
def mostrar_disponibles(self):
print("Vehículos disponibles en la tienda:")
for vehiculo in self.inventario:
if vehiculo.esta_disponible():
print(f"{vehiculo.marca} - {vehiculo.get_price()}")
Lo más importante de este diseño es que la concesionaria no interactúa directamente con las clases hija (Auto, Bicicleta, Camion), sino con los parámetros y métodos establecidos en la clase padre Vehiculo [03:00]. Esto es la abstracción en acción: se trabaja con una interfaz común sin preocuparse por la implementación específica de cada tipo de vehículo.
Con todas las clases definidas, el siguiente paso natural es crear las instancias y poner en práctica los cuatro fundamentos de la programación orientada a objetos: herencia, polimorfismo, encapsulación y abstracción [10:20]. ¿Qué tipo de vehículo agregarías primero al inventario?
Programación Orientada a Objetos: Implementación de Clases y Herencia