11.4 Mantošana un super()

Tavs šīs stundas izaicinājums: Apgūt klašu hierarhiju, izveidojot specializētas bērna klases ar mantotu un papildinātu uzvedību.

SR 2.4.18. Lieto OOP pamatus SR 2.4.15. Modulāras programmas un funkcijas

Teorija: Mantošana — kods atkārtoti lietojams

Mantošana ļauj izveidot specializētas klases no vispārējām. Vecāku klase satur kopīgo loģiku, bērna klase pievieno specifisko.

class Varonis:
    def __init__(self, vards, hp=100, speks=10):
        self.vards = vards
        self.hp = hp
        self.speks = speks

    def uzbrukums(self, merkis):
        merkis.hp -= self.speks

class Burvis(Varonis):
    def __init__(self, vards, mana=50):
        # Izsauc vecāku konstruktoru
        super().__init__(vards, hp=80, speks=5)
        self.mana = mana  # papildu atribūts

    def burvojums(self, merkis):
        if self.mana >= 10:
            self.mana -= 10
            merkis.hp -= 25
            print(f"{self.vards} izšauj uguni! ({merkis.vards} -25)")
        else:
            print("Nepietiek manas!")

class Bruninieks(Varonis):
    def __init__(self, vards):
        super().__init__(vards, hp=150, speks=18)
        self.brunas = 5

    # Pārraksta vecāku metodi (override)
    def cizt(self, b):
        b = max(0, b - self.brunas)  # bruņas absorbē
        super().cizt(b)

m = Burvis("Merlins")
b = Bruninieks("Lanselots")
m.burvojums(b)

isinstance(m, Varonis) atgriež True, jo Burvis ir Varonis.

1. uzdevums: Bērna klase

Izveido vienkāršu klases hierarhiju.

Izpildes soļi:

  1. Saglabā vecāku klasi Varonis no iepriekšējām stundām.
  2. Izveido class Bruninieks(Varonis), kas izsauc super().__init__(vards, hp=150, speks=18).
  3. Pievieno self.brunas = 5 atribūtu.
  4. Izveido objektu un pārbaudi, vai mantotā uzbrukums() metode strādā.

2. uzdevums: Metodes pārrakstīšana (override)

Izmaina vecāku uzvedību bērnu klasē.

Izpildes soļi:

  1. Klasei Bruninieks pievieno def cizt(self, b), kas atņem self.brunas no bojājuma.
  2. Izsauc vecāku metodi: super().cizt(jaunais_bojajums).
  3. Pārbaudi: ar 10 bojājumu, bruņinieks zaudē tikai 5 HP (jo bruņas 5).
  4. Pievieno otru bērna klasi Strelnieks(Varonis) ar augstāku speks, bet zemu hp.

3. uzdevums: Daudzpakāpju hierarhija

Veido klašu koku ar 3 līmeņiem.

Izpildes soļi:

  1. Izveido class Burvis(Varonis) ar self.mana.
  2. Izveido class UgunsBurvis(Burvis), kas pievieno spēju uguns_lietus, kas izšauj 50 bojājumu, bet patērē 25 manas.
  3. Pārbaudi isinstance(ub, Varonis) un isinstance(ub, Burvis) — abi True.
  4. Demonstrē, ka UgunsBurvis manto gan Burvis, gan Varonis metodes.

Papildus uzdevums: Vairākkārtēja mantošana

Klase manto no vairākām vecāku klasēm.

Izpildes soļi:

  1. Definē class Lidotajs ar metodi lidot().
  2. Definē class Pukis(Varonis, Lidotajs).
  3. Pārbaudi, ka pūķis var gan uzbrukums(), gan lidot().
  4. Izpēti MRO: print(Pukis.__mro__) — kā Python meklē metodes.

Biežākās kļūdas

Koda piemērs

class Varonis:
    def __init__(self, vards, hp=100, speks=10):
        self.vards = vards
        self.hp = hp
        self.speks = speks

class Bruninieks(Varonis):
    def __init__(self, vards):
        super().__init__(vards, hp=150, speks=18)
        self.brunas = 5

    def cizt(self, b):
        b = max(0, b - self.brunas)
        self.hp = max(0, self.hp - b)
        print(f"{self.vards} bruņas absorbēja, atlikušais {self.hp} HP")

bruno = Bruninieks("Lanselots")
bruno.cizt(20)  # bruņas absorbē 5 → faktiski 15 bojājuma
print(f"isinstance(bruno, Varonis) = {isinstance(bruno, Varonis)}")
Lanselots bruņas absorbēja, atlikušais 135 HP
isinstance(bruno, Varonis) = True
⬅ Iepriekšējā stunda Nākamā stunda ➡