it-praxisportal/10_vererbung_und_super/aufgabe.py

284 lines
12 KiB
Python

"""
Kapitel 10: Vererbung (Inheritance) & super() 🧬🚗
===================================================
Schulabgleich: 25.0 Vererbung
Aufgabe:
Erstelle eine Hierarchie von Fahrzeugen für eine moderne Fahrzeugflotte.
Nutze Vererbung (DRY-Prinzip) und super().__init__(), um gemeinsame Attribute
und Methoden von der Basisklasse 'Fahrzeug' an 'Auto', 'ElektroAuto' und 'Lkw' zu vererben.
"""
from typing import List, Optional
class Fahrzeug:
"""
Basisklasse für alle Fahrzeuge.
Attribute:
marke (str): Hersteller (z.B. "BMW", "Tesla", "MAN")
modell (str): Modellbezeichnung (z.B. "i4", "Model 3", "TGX")
baujahr (int): Baujahr des Fahrzeugs (z.B. 2022)
grundpreis (float): Ursprünglicher Neupreis in Euro
kilometerstand (float): Bereits gefahrene Kilometer (Startwert: 0.0)
"""
# ==========================================================================
# TODO 1: Konstruktor __init__ der Basisklasse
# Parameter: marke (str), modell (str), baujahr (int), grundpreis (float)
# Attribute:
# - self.marke: str
# - self.modell: str
# - self.baujahr: int
# - self.grundpreis: float (als float konvertieren)
# - self.kilometerstand: float (Startwert: 0.0)
# ==========================================================================
def __init__(self, marke: str, modell: str, baujahr: int, grundpreis: float):
pass
# ==========================================================================
# TODO 2: Methode fahren(self, km: float) -> None
# Erhöht den Kilometerstand um 'km', wenn km > 0 ist.
# Bei km <= 0 passiert nichts.
# ==========================================================================
def fahren(self, km: float) -> None:
pass
# ==========================================================================
# TODO 3: Methode berechne_restwert(self, aktuelles_jahr: int) -> float
# Berechnet den aktuellen Restwert des Fahrzeugs:
# 1. Alter = max(0, aktuelles_jahr - self.baujahr)
# 2. Wertverlust = self.grundpreis * 0.05 * Alter (5% Wertverlust pro Jahr)
# 3. Restwert = self.grundpreis - Wertverlust
# 4. Mindestrestwert ist 10% des Grundpreises: max(self.grundpreis * 0.10, Restwert)
# Rückgabe: Restwert als float
# ==========================================================================
def berechne_restwert(self, aktuelles_jahr: int) -> float:
pass
# ==========================================================================
# TODO 4: Methode info(self) -> str
# Gibt einen formatierten Infostring zurück:
# Format: "{marke} {modell} ({baujahr}) - {kilometerstand:.1f} km"
# Beispiel: "BMW 320d (2020) - 45000.0 km"
# ==========================================================================
def info(self) -> str:
pass
def __str__(self) -> str:
return self.info()
class Auto(Fahrzeug):
"""
Abgeleitete Klasse für PKWs (erbt von Fahrzeug).
Zusätzliche Attribute:
sitzplaetze (int): Anzahl der Sitze (Standardwert: 5)
anzahl_tueren (int): Anzahl der Türen (Standardwert: 5)
"""
# ==========================================================================
# TODO 5: Konstruktor __init__ von Auto
# Parameter: marke (str), modell (str), baujahr (int), grundpreis (float),
# sitzplaetze (int = 5), anzahl_tueren (int = 5)
# 1. Rufe den Konstruktor der Elternklasse mit super().__init__(...) auf!
# 2. Setze self.sitzplaetze und self.anzahl_tueren
# ==========================================================================
def __init__(
self,
marke: str,
modell: str,
baujahr: int,
grundpreis: float,
sitzplaetze: int = 5,
anzahl_tueren: int = 5,
):
pass
# ==========================================================================
# TODO 6: Methode hupen(self) -> str
# Gibt einen Hup-Laut mit Marke und Modell zurück:
# Format: "Hup hup! Platz da für den {marke} {modell}!"
# Beispiel: "Hup hup! Platz da für den VW Golf!"
# ==========================================================================
def hupen(self) -> str:
pass
# ==========================================================================
# TODO 7: Methode info(self) -> str (Method Overriding / Erweitern)
# Rufe super().info() auf und hänge " | {sitzplaetze} Sitze, {anzahl_tueren} Türen" an.
# Format: "{super().info()} | {self.sitzplaetze} Sitze, {self.anzahl_tueren} Türen"
# Beispiel: "VW Golf (2021) - 12000.0 km | 5 Sitze, 5 Türen"
# ==========================================================================
def info(self) -> str:
pass
class ElektroAuto(Auto):
"""
Abgeleitete Klasse für Elektroautos (Mehrstufige Vererbung: erbt von Auto).
Zusätzliche Attribute:
batterie_kapazitaet_kwh (float): Maximale Akkukapazität in Kilowattstunden
batterie_ladestand_kwh (float): Aktueller Ladestand (Startwert: voll = batterie_kapazitaet_kwh)
verbrauch_pro_100km (float): Verbrauch in kWh auf 100 km (Standardwert: 18.0)
"""
# ==========================================================================
# TODO 8: Konstruktor __init__ von ElektroAuto
# Parameter: marke (str), modell (str), baujahr (int), grundpreis (float),
# batterie_kapazitaet_kwh (float), sitzplaetze (int = 5),
# anzahl_tueren (int = 5), verbrauch_pro_100km (float = 18.0)
# 1. Rufe super().__init__(marke, modell, baujahr, grundpreis, sitzplaetze, anzahl_tueren) auf.
# 2. Setze self.batterie_kapazitaet_kwh = float(batterie_kapazitaet_kwh)
# 3. Setze self.batterie_ladestand_kwh = float(batterie_kapazitaet_kwh) (Akku ist anfangs voll)
# 4. Setze self.verbrauch_pro_100km = float(verbrauch_pro_100km)
# ==========================================================================
def __init__(
self,
marke: str,
modell: str,
baujahr: int,
grundpreis: float,
batterie_kapazitaet_kwh: float,
sitzplaetze: int = 5,
anzahl_tueren: int = 5,
verbrauch_pro_100km: float = 18.0,
):
pass
# ==========================================================================
# TODO 9: Methode reichweite(self) -> float
# Berechnet die verbleibende Reichweite in Kilometern:
# Formel: (aktueller_ladestand / verbrauch_pro_100km) * 100
# Wenn verbrauch_pro_100km <= 0: 0.0 zurückgeben.
# ==========================================================================
def reichweite(self) -> float:
pass
# ==========================================================================
# TODO 10: Methode fahren(self, km: float) -> bool (Überschreiben mit Logik)
# 1. Wenn km <= 0: False zurückgeben.
# 2. Berechne den benötigten Strom: benoetigt = (km / 100.0) * self.verbrauch_pro_100km
# 3. Wenn self.batterie_ladestand_kwh >= benoetigt:
# - Ziehe den Verbrauch vom Ladestand ab: self.batterie_ladestand_kwh -= benoetigt
# - Rufe super().fahren(km) auf (damit der Kilometerstand erhöht wird!)
# - return True
# 4. Wenn der Akku NICHT reicht:
# - Fahre nicht (keine Änderung an Kilometerstand oder Akku)
# - return False
# ==========================================================================
def fahren(self, km: float) -> bool:
pass
# ==========================================================================
# TODO 11: Methode aufladen(self, kwh: float) -> float
# Lädt den Akku auf, aber maximal bis batterie_kapazitaet_kwh!
# 1. Wenn kwh <= 0: return 0.0
# 2. Berechne den freien Platz im Akku: batterie_kapazitaet_kwh - batterie_ladestand_kwh
# 3. Tatsächlich geladene Menge = min(freier_platz, kwh)
# 4. Erhöhe batterie_ladestand_kwh um die geladene Menge
# 5. Gib die tatsächlich geladene Menge (float) zurück.
# ==========================================================================
def aufladen(self, kwh: float) -> float:
pass
# ==========================================================================
# TODO 12: Methode info(self) -> str
# Format: "{super().info()} | Akku: {batterie_ladestand_kwh:.1f}/{batterie_kapazitaet_kwh:.1f} kWh ({reichweite():.1f} km Reichweite)"
# Beispiel: "Tesla Model 3 (2023) - 5000.0 km | 5 Sitze, 5 Türen | Akku: 60.0/60.0 kWh (333.3 km Reichweite)"
# ==========================================================================
def info(self) -> str:
pass
class Lkw(Fahrzeug):
"""
Abgeleitete Klasse für Lastkraftwagen (erbt direkt von Fahrzeug).
Zusätzliche Attribute:
max_zuladung_kg (float): Maximale Frachtkapazität in kg
aktuelle_ladung_kg (float): Aktuell geladene Fracht (Startwert: 0.0)
"""
# ==========================================================================
# TODO 13: Konstruktor __init__ von Lkw
# Parameter: marke (str), modell (str), baujahr (int), grundpreis (float),
# max_zuladung_kg (float)
# 1. Rufe super().__init__(marke, modell, baujahr, grundpreis) auf.
# 2. Setze self.max_zuladung_kg = float(max_zuladung_kg)
# 3. Setze self.aktuelle_ladung_kg = 0.0
# ==========================================================================
def __init__(
self,
marke: str,
modell: str,
baujahr: int,
grundpreis: float,
max_zuladung_kg: float,
):
pass
# ==========================================================================
# TODO 14: Methode beladen(self, kg: float) -> bool
# 1. Wenn kg > 0 und self.aktuelle_ladung_kg + kg <= self.max_zuladung_kg:
# - Erhöhe self.aktuelle_ladung_kg um kg
# - return True
# 2. Sonst (Überladung oder ungültiges Gewicht): return False
# ==========================================================================
def beladen(self, kg: float) -> bool:
pass
# ==========================================================================
# TODO 15: Methode entladen(self, kg: float) -> float
# Entlädt maximal die vorhandene Ladung.
# 1. Wenn kg <= 0: return 0.0
# 2. tatsaechlich = min(self.aktuelle_ladung_kg, kg)
# 3. self.aktuelle_ladung_kg -= tatsaechlich
# 4. return tatsaechlich
# ==========================================================================
def entladen(self, kg: float) -> float:
pass
# ==========================================================================
# TODO 16: Methode info(self) -> str
# Format: "{super().info()} | Ladung: {aktuelle_ladung_kg:.1f}/{max_zuladung_kg:.1f} kg"
# Beispiel: "MAN TGX (2019) - 150000.0 km | Ladung: 8500.0/18000.0 kg"
# ==========================================================================
def info(self) -> str:
pass
# ==============================================================================
# Terminal-Test zum Ausprobieren: (python3 aufgabe.py)
# ==============================================================================
if __name__ == "__main__":
print("--- 🚗 Auto testen ---")
golf = Auto("VW", "Golf 8", 2021, 28000.0, sitzplaetze=5, anzahl_tueren=5)
golf.fahren(150.0)
print(golf.info())
print(golf.hupen())
print(f"Restwert im Jahr 2026: {golf.berechne_restwert(2026):.2f} €")
print("\n--- ⚡ ElektroAuto testen ---")
tesla = ElektroAuto("Tesla", "Model Y", 2023, 45000.0, batterie_kapazitaet_kwh=75.0, verbrauch_pro_100km=16.5)
print(tesla.info())
print(f"Start-Reichweite: {tesla.reichweite():.1f} km")
erfolg = tesla.fahren(200.0)
print(f"Fahrt 200 km erfolgreich? {erfolg}")
print(tesla.info())
geladen = tesla.aufladen(50.0)
print(f"Aufgeladen: {geladen:.1f} kWh")
print(tesla.info())
print("\n--- 🚛 LKW testen ---")
lkw = Lkw("Mercedes-Benz", "Actros", 2020, 110000.0, max_zuladung_kg=24000.0)
lkw.beladen(15000.0)
lkw.fahren(400.0)
print(lkw.info())
entladen = lkw.entladen(5000.0)
print(f"Entladen: {entladen:.1f} kg -> Neue Ladung: {lkw.aktuelle_ladung_kg:.1f} kg")