Python pärimise: ühepärimine, ülekirjutamine, mitmepärimine

1. Python pärandi ülevaade

Pythonis on pärand mehhanism, mille kaudu alamklass pärib vanemklassi funktsioone ja atribuute. Selle tulemusena paraneb koodi taaskasutatavus ja hoolduse tõhusus. See on üks objektorienteeritud programmeerimise (OOP) olulisi kontseptsioone ning on eriti kasulik suurte süsteemide arendamisel ja pikaajalistes projektides.

Pärandi põhilised rollid

  • Koodi taaskasutatavus: kuna klassi funktsioone, mis on kord korra kirjutatud, saab kasutada ka teistes klassides, saab vältida dubleeruvat koodi.
  • Hoolse lihtsus: kuna vanemklassi muudatused kajastuvad automaatselt alamklassides, saab parandusi ja funktsioonide laiendusi tõhusalt teha.
class ParentClass:
    def greet(self):
        print("Tere, see on vanemklass.")

class ChildClass(ParentClass):
    def greet(self):
        print("Tere, see on alamklass.")
Selles näites ChildClass kirjutab üle ParentClassi meetodi. Kuna greet meetod on üle kirjutatud, kuvab alamklass omaenda tervituse.

2. Pythonis üksik pärandamine

Üksik pärandamine tähendab, et üks lapsklass pärib funktsioone ühest vanemklassist. See on Pythoni pärandi põhiline vorm, mis võimaldab hoida koodi lihtsana, kuid samas pakkuda laiendatavust.

Üksik pärandamise põhiline süntaks ja näide

class Car:
    def __init__(self, brand, color):
        self.brand = brand
        self.color = color

    def describe(self):
        print(f"See auto on {self.color} värvi {self.brand}.")

class ElectricCar(Car):
    def __init__(self, brand, color, battery_size):
        super().__init__(brand, color)
        self.battery_size = battery_size

    def describe_battery(self):
        print(f"Aku maht on {self.battery_size}kWh.")
Selles näites lisab ElectricCar klass Car klassi funktsioonide pärimisele lisaks aku mahtu kirjeldava funktsiooni. super() abil kutsutakse vanemklassi konstruktor, et initsialiseerida ühised omadused (bränd ja värv).

3. Meetodi ülekirjutamine

Ülekirjutamine on funktsioon, mille abil alamklass määratleb vanemklassi meetodi uuesti. Sellega on võimalik kasutada vanemklassi meetodit, kuid muuta käitumist alamklassis.

Ülekirjutamise näide

class Animal:
    def speak(self):
        print("Looma häält")

class Dog(Animal):
    def speak(self):
        print("Wau wau!")
Selles näites Dog klass ülekirjutab Animal klassi speak meetodi. Sellega Dog klassi eksemplar väljastab „Wau wau“, kuid Animal klassi eksemplar kuvab „Looma häält“.

4. Mitmekordne pärimine

Mitmekordne pärimine võimaldab üks lapsklass pärida mitmest vanemklassist. Sellega saab erinevate klasside funktsionaalsuse ühendada ühte klassi, kuid see võib muuta rakenduse keerukaks, seega tuleb olla ettevaatlik.

Mitmekordse pärimise näited ja tähelepanekud

class A:
    def greet(self):
        print("A tervitus")

class B:
    def greet(self):
        print("B tervitus")

class C(A, B):
    pass

c = C()
c.greet()  # "A tervitus" kuvatakse (MRO järgi eelistatakse esimest klassi)
Pythonis määrab MRO (Method Resolution Order), millise vanemklassi meetod kutsutakse. Selle järjekorra kontrollimiseks kasutatakse C.mro(). Mitmekordne pärimine on võimas, kuid tuleb olla teadlik vanemklassi konfliktidest ja meetodite järjekorrast.

5. Pärimise kasutamise praktilised näited

Pärimine on kasulik paljudes igapäevastes programmeerimisolukordades. Näiteks ettevõtte töötajate haldussüsteemis saab põhiklassist töötajatest pärida spetsiifilise ametikohaga klassi, mis võimaldab koodi taaskasutamist ja laiendamist.

Töötajate haldussüsteemi praktiline näide

class Employee:
    def __init__(self, first, last, pay):
        self.first = first
        self.last = last
        self.pay = pay

    def fullname(self):
        return f'{self.first} {self.last}'

class Manager(Employee):
    def __init__(self, first, last, pay, employees=None):
        super().__init__(first, last, pay)
        self.employees = employees if employees is not None else []

    def add_employee(self, employee):
        if employee not in:
            self.employees.append(employee)

    def print_employees(self):
        for emp in self.employees:
            print(emp.fullname())
Selles näites pärib Manager klass Employee klassi ja lisab töötajate haldusfunktsiooni. Säilitades vanemklassi ühised funktsioonid, laiendatakse funktsionaalsust vastavalt konkreetsele ametikohale.

6. Pärimise parimad praktikad ja võrdlus kompositsiooniga

Pärimine on väga võimas, kuid liigne kasutamine võib koodi keerukaks muuta. Eriti mitmekordne pärimine võib klasside vahelisi suhteid muuta keerukaks, seega tuleks seda kasutada ettevaatlikult. Sellistes olukordades soovitatakse kasutada pärimise asemelkompositsiooni.

Kompositsiooni näide

Kompositsioon on kujundusmuster, kus üks klass omab teist klassi (eksemplari) komponendina, et funktsioone delegeerida.
class Engine:
    def start(self):
        print("Mootor käivitati.")

class Car:
    def __init__(self, engine):
        self.engine = engine

    def start(self):
        self.engine.start()

engine = Engine()
car = Car(engine)
car.start()  # "Mootor käivitati." kuvatakse
Nii on kompositsioon meetod, kuidas jagada funktsioone klasside vahel ilma pärimiseta. Ainult vajalike funktsioonide lisamisega muutub kood paindlikumaks ja hallatavaks.

7. Kokkuvõte

Pythoni pärimine on võimas tööriist, mis suurendab koodi taaskasutust ja laiendatavust. Mõistes selliseid tehnikaid nagu üksikpärimine, mitmekordne pärimine ja ülekirjutamine, saate luua tõhusaid ja hästi hooldatavaid programme. Samas on oluline olla teadlik kompositsiooni ja pärimise kasutamise erinevustest ning kavandada asjakohaselt. Õigesti kasutades pärimist, saate ehitada paindlikku ja tugevat koodibaasi.