CodeGym /Kursy /Python SELF PL /Inicjalizacja hierarchii

Inicjalizacja hierarchii

Python SELF PL
Poziom 16 , Lekcja 1
Dostępny

7.1 Metoda super()

Skoro rozmawiamy o hierarchii dziedziczenia, warto omówić niuanse pracy z polami i metodami klasy bazowej. W Pythonie jest specjalna metoda super(). Ta metoda służy do wywoływania metod klasy bazowej wewnątrz klasy pochodnej.

Ma trzy główne zastosowania:

Wywoływanie metod klasy rodzicielskiej:

Metoda super() pozwala wywołać metodę klasy rodzicielskiej z klasy pochodnej, nie podając jawnie nazwy klasy rodzicielskiej. To jest szczególnie przydatne przy pracy z wielokrotnym dziedziczeniem i pomaga unikać błędów przy zmianie hierarchii klas.

Inicjalizacja klas bazowych:

super() jest często używane w konstruktorze klasy pochodnej do wywoływania konstruktora klasy bazowej, co umożliwia inicjalizację atrybutów klasy bazowej w klasie pochodnej.

Wsparcie dla wielokrotnego dziedziczenia:

W przypadku wielokrotnego dziedziczenia super() prawidłowo rozwiązuje porządek wywoływania metod (MRO, Method Resolution Order), co sprawia, że jest preferowane przed jawnym wywoływaniem metod klas rodzicielskich. Omówimy to nieco później.

7.2 Konstruktor klasy bazowej

Konstruktor klasy bazowej musi być wywołany jawnie. Może się wydawać, że dzieje się to automatycznie, ale w rzeczywistości tak nie jest. Konstruktorów klas bazowych zawsze trzeba wywołać jawnie, ponieważ bardzo często trzeba do nich przekazać specjalne argumenty.

Przykład:


class Animal:
    def __init__(self, type, name):
        self.type = type
        self.name = name
         
        
class Dog(Animal):
    def __init__(self, name):
        super().__init__("Pies", name)  # Wywołanie konstruktora klasy bazowej
        
class Cat(Animal):
    def __init__(self, name):
        super().__init__("Kot", name)  # Wywołanie konstruktora klasy bazowej
        
        
# Tworzenie obiektu Dog
dog = Dog("Buddy")
print(dog) 

W tym przykładzie konstruktor klasy bazowej (Animal) ma dwa parametry: typ zwierzęcia i jego imię. Klasy dziedziczące mają tylko jeden — tylko imię.

To w konstruktorach klas Dog i Cat podjęta jest decyzja, co dokładnie przekazać do konstruktora klasy bazowej — nazwy typów zwierząt „Pies” i „Kot”.

Więc:

  • Konstruktor klasy bazowej trzeba koniecznie wywołać w konstruktorze klasy dziedziczącej.
  • Do tego trzeba użyć metody super().
  • Nie trzeba przekazywać parametru self osobno — Python zrobi to automatycznie przy wywoływaniu metody.

7.3 Użycie metody super()

Metoda super() w Pythonie może być używana nie tylko w konstruktorach, ale także w innych metodach klas do wywoływania metod klasy rodzicielskiej. To może być przydatne, gdy trzeba rozszerzyć lub zmodyfikować zachowanie metody zdefiniowanej w klasie rodzicielskiej.

Zobaczmy kilka przykładów:

Wywołanie metody klasy rodzicielskiej w metodzie klasy pochodnej

W tym przykładzie metoda speak() w klasie Dog najpierw wywołuje metodę speak() z klasy Animal za pomocą super(), a potem dodaje własne zachowanie.


class Animal:
    def speak(self):
        return "Jakieś ogólne dźwięki zwierzęcia"
        

class Dog(Animal):
    def speak(self):
        parent_speech = super().speak()  # Wywołanie metody klasy rodzicielskiej
        return f"{parent_speech} A pies szczeka!"
        
dog = Dog()
print(dog.speak())  # Wyświetli: Jakieś ogólne dźwięki zwierzęcia A pies szczeka!

Wywołanie metody klasy rodzicielskiej do sprawdzenia stanu

W tym przykładzie metoda check_health() w klasie Dog wywołuje metodę check_health() z klasy Animal, aby dodać dodatkowe sprawdzenia.


class Animal:
    def check_health(self):
        return "Zwierzę jest zdrowe"
        

class Dog(Animal):
    def check_health(self):
        parent_check = super().check_health()  # Wywołanie metody klasy rodzicielskiej
        return f"{parent_check}. Pies potrzebuje spaceru!"
        
dog = Dog()
print(dog.check_health())  # Wyświetli: Zwierzę jest zdrowe. Pies potrzebuje spaceru!

Wywołanie metody klasy rodzicielskiej w metodzie zmieniającej stan

W tym przykładzie metoda withdraw() w klasie SavingsAccount najpierw sprawdza, czy limit wypłat nie jest przekroczony, a jeśli nie, wywołuje metodę withdraw() z klasy BankAccount do wykonania operacji.


class BankAccount:
    def __init__(self, balance):
        self.balance = balance
        

    def withdraw(self, amount):
        if self.balance >= amount:
            self.balance -= amount
            return f"Wypłacono {amount}. Nowe saldo: {self.balance}"
        return "Niewystarczające środki"
        

class SavingsAccount(BankAccount):
    def withdraw(self, amount):
        if amount > 1000:
            return "Przekroczono limit wypłat"
        return super().withdraw(amount)  # Wywołanie metody klasy rodzicielskiej
        

savings = SavingsAccount(1500)
print(savings.withdraw(500))  # Wyświetli: Wypłacono 500. Nowe saldo: 1000
print(savings.withdraw(1500))  # Wyświetli: Przekroczono limit wypłat
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION