C# keeles on klass (class) kasutaja poolt defineeritud viitetüüp (reference type), mis on objektorienteeritud programmeerimise alustala ning toimib objektide loomise kavandina või mustrina. Klassid koondavad andmeid ja käitumist ühtseks loogiliseks üksuseks.
Siin on põhjalik ülevaade klassidest tuginedes allikatele:
1. Klassi olemus ja mälu
- Viitetüüp: Klassid on viitetüübid, mis tähendab, et kui loote objekti, eraldatakse sellele mälu kuhjas (managed heap). Muutuja ise hoiab vaid viidet (mäluaadressi) sellele objektile.
- Blueprint: Klassi deklaratsioon on kui joonis, mille põhjal luuakse tööajal isendid ehk objektid. Ühest klassist saab luua piiramatult objekte, millest igaühel on oma andmed.
- Ühtne tüübisüsteem: Kõik C# klassid pärinevad otseselt või kaudselt ühisest baasklassist
System.Object.
2. Klassi liikmed
Klass koosneb erinevatest liikmetest, mis määravad selle andmed ja funktsionaalsuse:
- Väljad (fields): Klassi sisesed muutujad andmete hoidmiseks.
- Omadused (properties): Võimaldavad kontrollitud ligipääsu andmetele
getjasetaktsessorite kaudu. C# 14 tutvustas märksõnafield, mis võimaldab kirjutada omadusi ilma käsitsi taustavälja deklareerimata. - Meetodid: Koodiplokid, mis sooritavad tegevusi.
- Konstruktorid: Erimetodid, mida kutsutakse välja objekti loomisel (
newmärksõnaga), et algväärtustada selle liikmed. - Sündmused (events): Võimaldavad klassil teavitada teisi objekte teatud tegevuste toimumisest.
3. Pääsumodifikaatorid
Klassi liikmete nähtavust kontrollitakse modifikaatoritega:
public: Juurdepääs on lubatud igalt poolt.private: Juurdepääs on lubatud ainult sama klassi seest (vaikimisi tase liikmetele).protected: Juurdepääs on lubatud samas klassis ja sellest tuletatud klassides.internal: Juurdepääs on lubatud ainult sama projekti (kooste) piires.
4. Eri tüüpi klassid ja modifikaatorid
- static: Staatilisest klassist ei saa luua eksemplare; kõik selle liikmed peavad olema staatilised ja need kuuluvad klassile endale, mitte objektidele.
- abstract: Abstraktne klass on mõeldud ainult baasklassiks teistele klassidele ning sellest ei saa luua otseseid isendeid.
- sealed: Suletud klass, millest ei saa edasi pärida.
- partial: Võimaldab ühe klassi definitsiooni jagada mitme eraldi faili vahel, mis on kasulik automaatselt genereeritud koodi puhul.
5. Klassid ja OOP põhimõtted
Klassid on vahendiks nelja peamise objektorienteeritud põhimõtte rakendamiseks:
- Pärilus (Inheritance): Võimalus luua uusi klasse olemasolevate põhjal, kasutades süntaksit
class SubClass : BaseClass. - Polümorfism: Võimalus üle kirjutada baasklassi meetodeid (
virtualjaoverride), et muuta käitumist tuletatud klassides. - Kapseldus: Sisemiste detailide peitmine ja ainult vajaliku liidese paljastamine.
- Abstraktsioon: Keeruliste süsteemide mudeldamine asjakohaste klasside ja atribuutide abil.
Uuendusena pakub C# 14 ka laiendusliikmeid (extension members), mis võimaldavad lisada olemasolevatele klassidele uusi meetodeid ja omadusi ilma neid muutmata või neist pärimata.
1. Klassi põhistruktuur
public class Isik
{
// VÄLJAD (fields) – privaatsed andmed
private string _nimi;
private int _vanus;
// OMADUSED (properties) – kontrollitud ligipääs
public string Nimi
{
get { return _nimi; }
set { _nimi = value; }
}
// Lühike omadus (auto-property)
public int Vanus { get; set; }
// Kirjutuskaitstud omadus
public bool OnTäisealine => _vanus >= 18;
// KONSTRUKTOR – objekti loomisel kutsutakse välja
public Isik(string nimi, int vanus)
{
_nimi = nimi;
_vanus = vanus;
}
// MEETOD
public void Tervita()
{
Console.WriteLine($"Tere! Olen {_nimi}, {_vanus} aastane.");
}
}
// Objekti loomine
Isik isik1 = new Isik("Mari", 25);
Isik isik2 = new Isik("Jaan", 17);
isik1.Tervita(); // Tere! Olen Mari, 25 aastane.
Console.WriteLine(isik2.OnTäisealine); // False
2. Konstruktorid
public class Auto
{
public string Mark { get; set; }
public string Mudel { get; set; }
public int Aasta { get; set; }
// Vaikekonstruktor
public Auto()
{
Mark = "Tundmatu";
Mudel = "Tundmatu";
Aasta = 2000;
}
// Parameetritega konstruktor
public Auto(string mark, string mudel, int aasta)
{
Mark = mark;
Mudel = mudel;
Aasta = aasta;
}
// Konstruktor kutsub teist konstruktorit
public Auto(string mark, string mudel) : this(mark, mudel, 2024)
{
}
public override string ToString()
=> $"{Mark} {Mudel} ({Aasta})";
}
// Erinevad loomisviisid
Auto a1 = new Auto();
Auto a2 = new Auto("Toyota", "Corolla", 2020);
Auto a3 = new Auto("BMW", "X5");
Console.WriteLine(a1); // Tundmatu Tundmatu (2000)
Console.WriteLine(a2); // Toyota Corolla (2020)
Console.WriteLine(a3); // BMW X5 (2024)
3. Pääsumodifikaatorid
public class Pangakonto
{
// private – ainult klassi sees
private double _saldo;
private string _pin;
// public – kõigile nähtav
public string Omanik { get; }
// protected – ka alamklassides nähtav
protected string Kontonumber { get; }
// internal – ainult projekti sees
internal DateTime LoodudKuupäev { get; }
public Pangakonto(string omanik, string pin, double algsaldo)
{
Omanik = omanik;
_pin = pin;
_saldo = algsaldo;
LoodudKuupäev = DateTime.Now;
}
// Avalik meetod – kasutab privaatset välja
public bool KontrolliPin(string pin) => _pin == pin;
public void Tõsta(double summa, string pin)
{
if (!KontrolliPin(pin))
{
Console.WriteLine("Vale PIN!");
return;
}
if (summa > _saldo)
{
Console.WriteLine("Ebapiisav saldo!");
return;
}
_saldo -= summa;
Console.WriteLine($"Väljastatud {summa}€. Saldo: {_saldo}€");
}
public double VaataSaldo(string pin)
{
if (!KontrolliPin(pin)) return -1;
return _saldo;
}
}
var konto = new Pangakonto("Mari", "1234", 1000);
konto.Tõsta(200, "1234"); // Väljastatud 200€. Saldo: 800€
konto.Tõsta(500, "0000"); // Vale PIN!
4. Eri tüüpi klassid
Static klass
// Staatilisest klassist ei saa objekte luua
public static class Matemaatika
{
public static double PI = 3.14159;
public static double Ruut(double x) => x * x;
public static double Ringjoon(double r) => 2 * PI * r;
public static bool OnAlgarv(int n)
{
if (n < 2) return false;
for (int i = 2; i <= Math.Sqrt(n); i++)
if (n % i == 0) return false;
return true;
}
}
// Kasutamine ilma objektita
Console.WriteLine(Matemaatika.Ruut(5)); // 25
Console.WriteLine(Matemaatika.OnAlgarv(17)); // True
Abstract klass
// Abstraktsest klassist ei saa otse objekte luua
public abstract class Loom
{
public string Nimi { get; set; }
public Loom(string nimi) => Nimi = nimi;
// Abstraktne meetod – PEAB olema alamklassis
public abstract string TeeSHääl();
// Tavaline meetod – päritakse
public void Tutvusta()
=> Console.WriteLine($"Olen {Nimi} ja ütlen: {TeeSHääl()}");
}
public class Koer : Loom
{
public Koer(string nimi) : base(nimi) { }
public override string TeeSHääl() => "Auh!";
}
public class Kass : Loom
{
public Kass(string nimi) : base(nimi) { }
public override string TeeSHääl() => "Mjäu!";
}
Loom[] loomad = { new Koer("Rex"), new Kass("Miki") };
foreach (var loom in loomad)
loom.Tutvusta();
// Olen Rex ja ütlen: Auh!
// Olen Miki ja ütlen: Mjäu!
Sealed klass
// Sealed klassist ei saa pärida
public sealed class Konfiguratsioon
{
public string ServerAadress { get; } = "localhost";
public int Port { get; } = 8080;
}
// Järgmine kood annaks VIGA:
// public class MuuKonfig : Konfiguratsioon { }
5. OOP Põhimõtted
Pärilus (Inheritance)
public class Sõiduk
{
public string Mark { get; set; }
public int Kiirus { get; protected set; }
public Sõiduk(string mark) => Mark = mark;
public virtual void Kiirendam(int summa)
{
Kiirus += summa;
Console.WriteLine($"{Mark} kiirus: {Kiirus} km/h");
}
}
public class Elektriauto : Sõiduk
{
public int Aku { get; private set; } = 100;
public Elektriauto(string mark) : base(mark) { }
// override – kirjutab üle baasklassi meetodi
public override void Kiirendam(int summa)
{
Aku -= summa / 10;
base.Kiirendam(summa); // kutsub baasklassi meetodit
Console.WriteLine($"Aku: {Aku}%");
}
}
var tesla = new Elektriauto("Tesla");
tesla.Kiirendam(50);
// Tesla kiirus: 50 km/h
// Aku: 95%
Polümorfism
public class Kujund
{
public virtual double Pindala() => 0;
public void Info() => Console.WriteLine($"Pindala: {Pindala():F2}");
}
public class Ring : Kujund
{
private double _raadius;
public Ring(double r) => _raadius = r;
public override double Pindala() => Math.PI * _raadius * _raadius;
}
public class Ristkülik : Kujund
{
private double _laius, _kõrgus;
public Ristkülik(double l, double k) { _laius = l; _kõrgus = k; }
public override double Pindala() => _laius * _kõrgus;
}
// Polümorfism – sama meetod, erinev käitumine
List<Kujund> kujundid = new()
{
new Ring(5),
new Ristkülik(4, 6),
new Ring(3)
};
foreach (var k in kujundid)
k.Info();
// Pindala: 78.54
// Pindala: 24.00
// Pindala: 28.27
Täisprogramm – kõik koos
using System;
using System.Collections.Generic;
// Abstraktne baasklass
public abstract class Töötaja
{
public string Nimi { get; }
public int Id { get; }
private static int _järjekord = 1;
protected Töötaja(string nimi)
{
Nimi = nimi;
Id = _järjekord++;
}
public abstract double ArvutaPalk();
public virtual void Info()
=> Console.WriteLine($"[{Id}] {Nimi} – Palk: {ArvutaPalk():F2}€");
}
// Alamklass – täistööajaga töötaja
public class TäisAeg : Töötaja
{
public double KuuPalk { get; }
public TäisAeg(string nimi, double kuuPalk) : base(nimi)
=> KuuPalk = kuuPalk;
public override double ArvutaPalk() => KuuPalk;
}
// Alamklass – osalise tööajaga töötaja
public class OsalineAeg : Töötaja
{
public double Tunnipalk { get; }
public int Tunnid { get; }
public OsalineAeg(string nimi, double tunnipalk, int tunnid) : base(nimi)
{
Tunnipalk = tunnipalk;
Tunnid = tunnid;
}
public override double ArvutaPalk() => Tunnipalk * Tunnid;
public override void Info()
{
base.Info();
Console.WriteLine($" → {Tunnid}h × {Tunnipalk}€");
}
}
// Staatiline abiklass
public static class PalgaArvutus
{
public static double KoguPalk(List<Töötaja> töötajad)
{
double kokku = 0;
foreach (var t in töötajad) kokku += t.ArvutaPalk();
return kokku;
}
}
class Program
{
static void Main()
{
var tiim = new List<Töötaja>
{
new TäisAeg("Mari", 2500),
new TäisAeg("Jaan", 3200),
new OsalineAeg("Peeter", 12.5, 80),
new OsalineAeg("Anna", 15.0, 60)
};
Console.WriteLine("Töötajate nimekiri:");
foreach (var t in tiim) t.Info();
Console.WriteLine($"\n Kokku palka: {PalgaArvutus.KoguPalk(tiim):F2}€");
}
}
```
**Väljund:**
```
Töötajate nimekiri:
[1] Mari – Palk: 2500.00€
[2] Jaan – Palk: 3200.00€
[3] Peeter – Palk: 1000.00€
→ 80h × 12.5€
[4] Anna – Palk: 900.00€
→ 60h × 15€
Kokku palka: 7600.00€
