﻿from abc import ABC, abstractmethod

# Klasa abstrakcyjna służąca jako kontrakt dla wszystkich wtyczek.
class PluginABC(ABC):
    
    @abstractmethod
    def inicjalizuj(self):
        """
        Abstrakcyjna metoda, którą każda wtyczka w systemie 
        powinna posiadać.
        """
        pass

# Zewnętrzna klasa (np. z biblioteki zewnętrznej, której kodu nie chcemy edytować).
# Zauważ, że NIE dziedziczy ona wprost z PluginABC.
class ThirdPartyPlugin:
    
    def inicjalizuj(self):
        # Mimo braku formalnego dziedziczenia, klasa dostarcza implementację
        # metody wymaganej przez nasz system.
        print("Trzeciorzędna wtyczka ładuje swoje zasoby...")
        
    def operacja_specyficzna(self):
        print("Wykonywanie niestandardowej operacji wtyczki.")


# REJESTRACJA WIRTUALNA
# Chociaż ThirdPartyPlugin nie dziedziczy po PluginABC, w ten sposób 
# "rejestrujemy" ją jako legalnego potomka (tzw. virtual subclass).
PluginABC.register(ThirdPartyPlugin)


if __name__ == "__main__":
    
    # Tworzymy obiekt "zewnętrznej" klasy
    zewnetrzny_obj = ThirdPartyPlugin()
    
    print("--- Weryfikacja typu instancji (isinstance) ---")
    # Zwróci True, mimo braku dziedziczenia w kodzie klasy!
    wynik_isinstance = isinstance(zewnetrzny_obj, PluginABC)
    print(f"Czy obiekt jest traktowany jako PluginABC? {wynik_isinstance}")
    
    print("\n--- Weryfikacja hierarchii (issubclass) ---")
    # Zwróci True, potwierdzając, że rejestracja zadziałała poprawnie.
    wynik_issubclass = issubclass(ThirdPartyPlugin, PluginABC)
    print(f"Czy klasa jest podklasą PluginABC? {wynik_issubclass}")
    
    print("\n--- Wywołanie zaimplementowanej metody ---")
    # Wywołujemy metodę, którą wtyczka zaimplementowała (zgodną z kontraktem)
    zewnetrzny_obj.inicjalizuj()

    # Wniosek edukacyjny:
    # Użycie PluginABC.register() jest idealne, gdy pracujemy z cudzym kodem 
    # (np. z zewnętrznych bibliotek). Zapewnia on płynną integrację, chociaż to 
    # my (programiści) ponosimy pełną odpowiedzialność, czy rejestrowana 
    # klasa w rzeczywistości ma wszystkie pożądane metody. Python tego automatycznie nie weryfikuje.
