﻿# OOP_LAB_4_zad_01.py
"""
Rozwiązanie zadania 1: Hierarchia pojazdów (Podstawy dziedziczenia)
"""

class Pojazd:
    """
    Klasa bazowa reprezentująca ogólny pojazd.
    Przechowuje uniwersalne atrybuty współdzielone przez wszystkie pojazdy.
    """
    def __init__(self, marka: str, model: str):
        # Inicjalizacja atrybutów bazowych, które będą dziedziczone przez klasy pochodne.
        # Unikamy dzięki temu powtarzania tego samego kodu (DRY - Don't Repeat Yourself).
        self.marka = marka
        self.model = model

    def info(self) -> str:
        """
        Zwraca podstawowe informacje o pojeździe.
        Ta metoda może być wywoływana lub rozszerzana (nadpisywana) w klasach pochodnych.
        """
        return f"Pojazd: {self.marka} {self.model}"


class Samochod(Pojazd):
    """
    Klasa pochodna reprezentująca samochód.
    Dziedziczy (is-a) po klasie Pojazd. Oznacza to, że każdy Samochod "jest" Pojazdem.
    """
    def __init__(self, marka: str, model: str, liczba_drzwi: int):
        # Używamy super() aby wywołać konstruktor klasy bazowej (Pojazd).
        # Dzięki temu poprawnie inicjalizujemy 'marka' i 'model', nie musimy przypisywać ich ręcznie.
        super().__init__(marka, model)
        # Dodajemy specyficzny atrybut tylko dla samochodu.
        self.liczba_drzwi = liczba_drzwi

    def info(self) -> str:
        """
        Nadpisujemy metodę info() z klasy bazowej, aby dodać szczegóły charakterystyczne dla samochodu.
        """
        # Ponownie używamy super() aby pobrać podstawowy opis z rodzica i jedynie go rozszerzyć.
        bazowe_info = super().info()
        return f"{bazowe_info}, Drzwi: {self.liczba_drzwi}"


class Motocykl(Pojazd):
    """
    Klasa pochodna reprezentująca motocykl. Kolejna specjalizacja pojazdu.
    """
    def __init__(self, marka: str, model: str, typ_napedu: str):
        # Wywołanie konstruktora bazowego dla atrybutów wspólnych.
        super().__init__(marka, model)
        # Dodanie unikalnej cechy dla motocykla.
        self.typ_napedu = typ_napedu

    def info(self) -> str:
        """
        Rozszerzamy metodę info() dla motocykla.
        """
        bazowe_info = super().info()
        return f"{bazowe_info}, Napęd: {self.typ_napedu}"


if __name__ == "__main__":
    # Testowanie utworzonej hierarchii dziedziczenia
    print("--- Testowanie klas Pojazd, Samochod, Motocykl ---")
    
    # Tworzenie instancji klasy Samochod
    s = Samochod("Ford", "Focus", 5)
    # Tworzenie instancji klasy Motocykl
    m = Motocykl("Yamaha", "R1", "Łańcuch")
    
    # Wywołanie odziedziczonej i rozszerzonej metody info()
    print(s.info())  # Zwróci: Pojazd: Ford Focus, Drzwi: 5
    print(m.info())  # Zwróci: Pojazd: Yamaha R1, Napęd: Łańcuch
    
    # Dowód na to, że Samochod "jest" Pojazdem (is-a)
    print(f"Czy 's' jest instancją klasy Pojazd? {isinstance(s, Pojazd)}")
