ebSkola

3.1 C# klases pamati

Stundas uzdevums: Saprast OOP fundamentālo konceptu - klases un objekti - un izveidot pirmo dalībnieka klasi.

SR 2.4.18. OOP pamati SR 2.4.15. Modulāras programmas

80 min plāns: Teorija un paraugs (~10 min) · 1. uzdevums (~20 min) - izveido pirmo klasi ar laukiem · 2. uzdevums (~25 min) - pievieno konstruktoru un metodes · 3. uzdevums (~20 min) - pārbaudi private un public atšķirību · Iesniegšana (~5 min).

Pirms sāc: šī ir pirmā stunda par klasēm. Atceries no Programmēšanas I vārdnīcas: dalibnieks = {"vards": "Anna", "energija": 100}. Klase ir tas pats, tikai ar iebūvētām funkcijām un stingru kārtību.

Teorija: C# klases struktūra

Klase ir veidne objektu radīšanai. Tā satur datus (atribūtus) un funkcijas (metodes).

public class Participant
{
    private int energy;      // tikai klases iekšienē pieejams
    private int maxEnergy;

    public string Name;
    public int Level = 1;

    // Konstruktors
    public Participant(string name, int energy)
    {
        Name = name;
        this.energy = energy;
        maxEnergy = energy;
    }

    // Metodes
    public void ApplyPenalty(int amount)
    {
        energy -= amount;
        if (energy < 0) energy = 0;
    }

    public bool IsActive()
    {
        return energy > 0;
    }

    public int GetEnergy() => energy;
}

public/private/protected kontrolē encapsulation (iekapsulāciju).

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.1 C# klases pamati";
    public bool UsesCSharp = true;
    public bool HasScriptFile = true;
    public bool HasSingleResponsibility = true;
    public bool UsesGodotInspector = true;
}

Praktiskie uzdevumi

1. uzdevums -

Izveido pirmo klasi ar laukiem

Beigās viens objekts glabās visus dalībnieka datus kopā.

  1. Uzraksti README.md failā Python vārdnīcu, kas glabā dalībnieka vārdu, enerģiju un līmeni.
  2. Izveido failu Participant.cs.
  3. Ieraksti public class Participant { }.
  4. Pievieno publiskus laukus ar atslēgvārdu public.
  5. Pieteic tajā laukus public string Name;, public int Energy; un public int Level = 1;.
  6. Izveido objektu citā failā un piešķir tā laukiem vērtības.
  7. Izdrukā visus trīs laukus un būvē projektu.

Gatavs, kad: izdrukā redzami visi trīs lauki, un tu vari parādīt, kura koda rinda atbilst kurai vārdnīcas atslēgai.

2. uzdevums -

Pievieno konstruktoru un metodes

Beigās objektu varēsi izveidot vienā rindā, un tas pats pratīs sevi mainīt.

  1. Pievieno klasē konstruktoru public Participant(string name, int energy) { Name = name; Energy = energy; }.
  2. Izveido objektu ar Participant p = new Participant("Anna", 100);.
  3. Pievieno metodi public void ApplyPenalty(int amount).
  4. Ieraksti tajā enerģijas samazināšanu un pārbaudi, ka tā nekļūst negatīva.
  5. Pievieno metodi public bool IsActive(), kas atgriež Energy > 0.
  6. Izsauc abas metodes un izdrukā rezultātu.
  7. Pieraksti, ar ko metode atšķiras no parastas funkcijas.

Gatavs, kad: objektu var izveidot vienā rindā, un pēc liela soda enerģija ir tieši 0, nevis negatīva.

3. uzdevums -

Pārbaudi private un public atšķirību

Beigās tu zināsi, kāpēc daļu datu paslēpj.

  1. Pārvieto lauku Energy uz privātu lauku private int energy;.
  2. Mēģini to nomainīt no ārpuses ar p.energy = 9999;.
  3. Būvē projektu un pieraksti kompilatora kļūdas tekstu.
  4. Pievieno publisku metodi public int GetEnergy().
  5. Nolasi enerģiju caur šo metodi un izdrukā to.
  6. Pieraksti, kāpēc ir labi, ka enerģiju var mainīt tikai caur ApplyPenalty().
  7. Pārliecinies, ka projekts būvējas bez kļūdām.

Gatavs, kad: tieša piekļuve privātam laukam dod kompilatora kļūdu, bet caur metodi vērtību nolasīt var.

Papildu uzdevums - Izveido komandu no trim dalībniekiem

Ja pamatdarbs ir gatavs, strādā ar vairākiem objektiem reizē.

  1. Pievieno faila sākumā using System.Collections.Generic;.
  2. Izveido List<Participant> team = new();.
  3. Pievieno tam trīs dalībniekus ar dažādām enerģijām.
  4. Uzraksti ciklu, kas izdrukā katra vārdu un enerģiju.
  5. Saskaiti ciklā, cik dalībnieku vēl ir aktīvi.

Gatavs, kad: cikls izdrukā visus trīs dalībniekus un pareizi saskaita aktīvos.

Ko sagatavo

Stundas mērķis: Tu proti C# uzrakstīt klasi ar laukiem, konstruktoru un metodēm, izveidot no tās objektu un paskaidrot, kāpēc daļa lauku ir private.

GitHub krātuvē jābūt:

  1. Fails Participant.cs.
  2. Ekrānuzņēmums ar Output paneli, kurā redzami dalībnieka dati un enerģija pēc soda.
  3. README.md: Python vārdnīca un tai atbilstošā C# klase blakus, un viens teikums, kāpēc energy ir private.

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 access private member: Mēģini piekļūt private laukam ārpus klases - lieto getter.
  • The name 'energy' does not exist: pārbaudi, vai lauka nosaukums sakrīt ar to, ko lieto metodēs.
  • CS0122 private kļūda: mēģini piekļūt privātam laukam ārpus klases - lieto GetEnergy().

Godot ekrānuzņēmumi

VS Code logs ar atvērtu Participant.cs - redzama klases struktūra ar private un public laukiem un metodēm.
VS Code logs ar atvērtu Participant.cs - redzama klases struktūra ar private un public laukiem un metodēm.
UML klases diagramma Participant ar atribūtiem name/energy/focus/calm un metodēm apply_penalty/is_active/print_status.
UML klases diagramma Participant ar atribūtiem name/energy/focus/calm un metodēm apply_penalty/is_active/print_status.

Koda piemērs (paplašināts)

using Godot;
using System;

public class Participant
{
    private int energy;
    private int maxEnergy;
    private int focus;
    private int calm;

    public string Name { get; }

    public Participant(string name, int energy, int focus, int calm)
    {
        Name = name;
        this.energy = energy;
        maxEnergy = energy;
        this.focus = focus;
        this.calm = calm;
    }

    public void ApplyPenalty(int amount)
    {
        int actual = Math.Max(0, amount - calm);
        energy = Math.Max(0, energy - actual);
        GD.Print(Name, " zaudē ", actual, " enerģijas punktus. ENERGY: ", energy);
    }

    public bool IsActive() => energy > 0;

    public void PrintStatus()
    {
        GD.Print(Name, " ENERGY: ", energy, "/", maxEnergy,
            " FOCUS: ", focus, " CALM: ", calm);
    }
}
Output: 'Anna ENERGY: 100/100 FOCUS: 15 CALM: 5' un pēc soda punktiem 'ENERGY: 80'.