ebSkola

3.2 Mantošana C# un Godot

Stundas uzdevums: Izveidot specializētas dalībnieku klases, izmantojot inheritance (mantošanu).

SR 2.4.18. OOP SR 2.4.15. Modulāras programmas

80 min plāns: Teorija un paraugs (~10 min) · 1. uzdevums (~20 min) - izveido bērna klasi · 2. uzdevums (~25 min) - pārraksti metodi ar override · 3. uzdevums (~20 min) - izsauc visas lomas vienā ciklā · Iesniegšana (~5 min).

Pirms sāc: atver savu Participant klasi no 3.1 stundas. Šodien no vienas klases taisīsi vairākas lomas, nekopējot kodu.

Teorija: Inheritance un virtuālas funkcijas

Mantošana ļauj bērna klasei pārmantot vecāka atribūtus un metodes, pievienojot vai pārrakstot.

public class Participant { /* base klase */ }

public class Captain : Participant
{
    public int Stability;

    public Captain(string name) : base(name, 150, 18, 12)  // izsauc vecāku konstruktoru
    {
        Stability = 10;
    }

    // Pārraksta (override) vecāka metodi
    public override void ApplyPenalty(int amount)
    {
        amount -= Stability;  // stabilitāte samazina soda punktus
        base.ApplyPenalty(amount);
    }
}

public class Presenter : Participant
{
    public int Ideas = 100;

    public Presenter(string name) : base(name, 80, 25, 3) { }

    public void PresentBonus(Participant target)
    {
        if (Ideas >= 20)
        {
            Ideas -= 20;
            target.ApplyPenalty(40);
        }
    }
}

virtual atslēgvārds ļauj izsaukt bērna metodi caur vecāka pointer (polimorfisms).

Kā šo izmantot projektā

Atceries: ar redzamu efektu editorā nepietiek. Paskaidro, kura C# klase glabā stāvokli, kura metode to maina un kā Godot node struktūra izmanto šo kodu.

Pārbaudi: katrai būtiskai turnīra lomai ir C# klase vienā .cs failā, ar konstruktoriem, metodēm, signāliem vai mantošanu.

public class OopCheckpoint
{
    public string Lesson = "3.2 Mantošana C# un Godot";
    public bool UsesCSharp = true;
    public bool HasScriptFile = true;
    public bool HasSingleResponsibility = true;
    public bool UsesGodotInspector = true;
}

Praktiskie uzdevumi

1. uzdevums -

Izveido bērna klasi

Beigās jaunā klase mantos visu no vecāku klases.

  1. Izveido failu Captain.cs.
  2. Ieraksti public class Captain : Participant { }.
  3. Pievieno konstruktoru public Captain(string name) : base(name, 150) { }.
  4. Pievieno privātu lauku private int stability = 10;.
  5. Izveido objektu Captain c = new Captain("Anna"); un izsauc tam IsActive().
  6. Pieraksti, no kurienes šī metode radās, ja tu to Captain klasē nerakstīji.
  7. Izdzēs : base(name, 150) daļu, būvē projektu un izlasi kļūdu.

Gatavs, kad: bērna objektam strādā vecāka metodes, bet bez vecāka konstruktora izsaukuma kods nekompilējas.

2. uzdevums -

Pārraksti metodi ar override

Beigās kapteinis sodu izturēs labāk nekā parasts dalībnieks.

  1. Pievieno vecāka klasē atslēgvārdu virtual pirms ApplyPenalty.
  2. Pievieno Captain klasē public override void ApplyPenalty(int amount).
  3. Ieraksti tajā amount = Math.Max(1, amount - stability);.
  4. Izsauc pēc tam vecāka versiju ar base.ApplyPenalty(amount);.
  5. Izmēģini vienādu sodu abiem: parastam dalībniekam un kapteinim.
  6. Pieraksti, cik enerģijas katrs zaudēja.
  7. Izdzēs virtual vārdu, būvē projektu un pieraksti, kas mainās.

Gatavs, kad: ar vienādu sodu kapteinis zaudē mazāk enerģijas nekā parasts dalībnieks.

3. uzdevums -

Izsauc visas lomas vienā ciklā

Beigās viens cikls apkalpos jebkuru lomu skaitu.

  1. Izveido vēl vienu bērna klasi Presenter ar citu enerģiju.
  2. Pārraksti arī tai ApplyPenalty savā veidā.
  3. Izveido List<Participant> party = new();.
  4. Pievieno tam pa vienam objektam no katras klases.
  5. Uzraksti ciklu, kas katram izsauc ApplyPenalty(20).
  6. Izdrukā pēc cikla katra vārdu un atlikušo enerģiju.
  7. Pieraksti, kāpēc cikls nezina, kura loma tam tiek padota.

Gatavs, kad: viens cikls apstrādā visas lomas, un katra zaudē atšķirīgu enerģijas daudzumu.

Papildu uzdevums - Pievieno trešo lomu

Ja pamatdarbs ir gatavs, paplašini hierarhiju.

  1. Izveido klasi TimeKeeper ar mazāku enerģiju, bet lielāku ātrumu.
  2. Pārraksti tai ApplyPenalty tā, lai tā zaudētu vairāk.
  3. Pievieno to sarakstam.
  4. Palaid ciklu vēlreiz un pārbaudi, vai kods bija jāmaina.
  5. Pieraksti, cik rindu bija jāpieraksta ciklā.

Gatavs, kad: trešā loma darbojas ciklā, un pašā ciklā nebija jāmaina neviena rinda.

Ko sagatavo

Stundas mērķis: Tu proti izveidot bērna klasi ar C# mantošanu, izsaukt vecāka konstruktoru, pārrakstīt metodi ar virtual un override un apstrādāt visas lomas vienā ciklā.

GitHub krātuvē jābūt:

  1. Faili Captain.cs un Presenter.cs.
  2. Ekrānuzņēmums ar Output paneli, kurā redzams, ka pēc vienāda soda lomām palikusi atšķirīga enerģija.
  3. README.md: kas notiek, ja no vecāka metodes noņem virtual.

Kā iesniedz: Veic commit un push. Skolotāja norādītajā vietā ievieto tikai GitHub krātuves saiti; visiem prasītajiem failiem, README.md pierakstiem un pierādījumiem jābūt pašā krātuvē.

Biežākās kļūdas

  • Cannot call base constructor: Trūkst initializer list ar : Participant(...).
  • 'override' was not declared: C#11+ vajadzīgs (Godot prasa C#17).
  • Slicing problem: Pieliecot Participant objektu, ne Participant*, polimorfisms nedarbojas.

Godot ekrānuzņēmumi

Klašu hierarhijas koks: Participant (base) → Captain, Presenter, TimeKeeper (visi public mantojuma).
Klašu hierarhijas koks: Participant (base) → Captain, Presenter, TimeKeeper (visi public mantojuma).

Koda piemērs (paplašināts)

using Godot;
using System;

public class Captain : Participant
{
    private int stability = 10;

    public Captain(string name) : base(name, 150, 18, 12) { }

    public override void ApplyPenalty(int amount)
    {
        amount = Math.Max(1, amount - stability);
        base.ApplyPenalty(amount);
    }
}

public class Presenter : Participant
{
    private int ideas = 100;

    public Presenter(string name) : base(name, 80, 25, 3) { }

    public void PresentBonus(Participant target)
    {
        if (ideas >= 20)
        {
            ideas -= 20;
            GD.Print(Name, " izmanto prezentācijas bonusu pret ", target.Name);
            target.ApplyPenalty(40);
        }
    }
}
Captain zaudē par 10 punktiem mazāk enerģijas, Presenter izmanto prezentācijas bonusu, kas samazina šķēršļa enerģiju par 40 punktiem.