Třída je základní stavební kámen objektově orientovaného programování (OOP).
Je to šablona, podle které se vytvářejí objekty (instance).
Třída definuje:
data, která objekt bude mít (tzv. členské proměnné nebo fields)
chování, tedy metody, které s těmito daty mohou pracovat
Každá třída si může udržovat svůj vnitřní stav (hodnoty vlastností, proměnných…) a je zodpovědná, aby se vždy nacházela ve validním stavu.
To znamená, že neobsahuje nesprávná data zadaná uživatelem a nesnaží se nad nimi dělat nějaké operace.
Objekt (instance) vzniká vyplněním šablony (třídy) konkrétními daty a následně existuje reálně v paměti počítače.
Ukázka třídy Car:
public class Car{ public string Brand; public int Year; public void Start() { Console.WriteLine("Auto nastartovalo."); }}
Z této třídy lze vytvořit objekty (instance):
Car myCar = new Car(){ Brand = "Škoda", Year = 2021;};myCar.Start();
Definice tříd
Třídy se definují pomocí klíčového slova class a mohou obsahovat:
Členské proměnné (fields)
Konstruktory (constructors)
Vlastnosti (properties)
Metody (methods)
Události (events)
Vnořené typy (Nested types)
Finalizéry (finalizers)
U tříd a jejich obsahu lze specifikovat odkud k nim lze přistupovat pomocí modifikátorů přístupu.
Zastiňování členů (Member shadowing)
Pokud se v rodičovské i odvozené třídě nachází člen se stejným názvem. Vždy se použije člen, který je nejblíže v hierarchii k použitému typu.
public class A{ public void PrintText() { ... }} public class B : A{ public void PrintText() { ... }}
Velmi zhoršuje čitelnost kódu, proto kompilátor navrhuje použít klíčové slovo new v definici metody ve třídě B.
public class A{ public void PrintText() { ... }} public class B : A{ public new void PrintText() { ... }}
Životní cyklus tříd
Instanciace – v běhu programu se vytvoří konkrétní objekt podle šablony třídy (pomocí new)
Použití – volání metod, přístup k datům objektu
Uvolnění z paměti – objekt přestane být používán, paměť se uvolní (v .NET prostřednictvím Garbage Collectoru)
Statický vs. instanční kontext
Třídy mohou být buďto instanční nebo statické v závislosti na účelu jejich existence. Více o kontextech lze najít zde: Statický vs. instanční kontext.
Obsah třídy
Členské proměnné (Fields)
Členské proměnné jsou proměnné deklarované přímo v těle třídy. Uchovávají data objektu.
public string Name;private int _age;
Vlastnosti (Properties)
Vlastnosti slouží ke zpřístupnění interních dat objektu (fields) bezpečným způsobem.
Mohou obsahovat logiku při čtení nebo zápisu hodnoty. Více o vlastnostech lze nalézt na stránce Vlastnosti.
public string Name { get; set; }
Metody (Methods)
Metody definují chování objektu. Může jít o běžné metody, přetížené metody, statické metody, virtuální nebo abstraktní metody atd. Více o metodách lze nalézt zde: Metody.
public void PrintName(){ Console.WriteLine(Name);}
Konstruktory (Constructors)
Konstruktor je speciální metoda, která se volá při vytváření objektu. Slouží k inicializaci objektu (např. nastavení defaultních hodnot).
má stejný název jako třída
nemá návratový typ
může být přetížený (více verzí s různými parametry)
public class Person{ public Person(string name, int age) { Name = name; Age = age; }}
Ukázka volání konstruktoru:
var person = new Person("Alice", 30);
Implicitní konstruktor
Pokud není napsán žádný konstruktor, tak kompilátor automaticky vytvoří výchozí konstruktor bez parametrů. Bez něj by například nebylo možné udělat toto:
var person = new Person();
Destruktory (Destructors)
Destruktor je speciální metoda, která se volá těsně před tím, než je objekt odstraněn z paměti (více o odstraňování z paměti zde: Správa paměti). V C# jsou destruktory nazývány jako finalizéry.
~Person(){ // Uvolnění unmanaged zdrojů}
Pozor na finalizér!
běžně se nepoužívá
finalizér nelze volat ručně (není metoda)
negarantuje se, kdy se spustí (nebo zda vůbec)
finalizéry snižují výkon (objekty s finalizérem se musejí „dofinalizovat“ ve speciální fázi GC)
Typicky se používá při práci s unmanaged resources, např. soubory, handly, GDI objekty.
Většinou se ale doporučuje místo finalizéru implementovat IDisposable (viz článek Disposable).
Kompletní ukázka
public class Person{ // Field private int _age; // Auto-property public string Name { get; set; } // Property s logikou public int Age { get => _age; set { if (value < 0) throw new ArgumentException("Věk nemůže být záporný."); _age = value; } } // Constructor public Person(string name, int age) { Name = name; Age = age; } // Method public void SayHello() { Console.WriteLine($"Ahoj, jmenuji se {Name} a je mi {Age} let."); } // Static Method public static void PrintGreeting() { Console.WriteLine("Zdraví vás třída Person!"); } // Finalizer ~Person() { Console.WriteLine("Objekt Person bude odstraněn z paměti."); }}
Použití:
var person = new Person("Alice", 30);person.SayHello();Person.PrintGreeting();
Partial třídy
Partial třídy rozdělit deklaraci jedné třídy do více souborů. To je užitečné zejména v případech, kdy část kódu generuje nástroj (např. Visual Studio pro návrh formulářů) a vývojář chce zachovat vlastní logiku odděleně, aby se nepřepsala.
Deklarace třídy jako partial říká kompilátoru, že definice této třídy může být rozdělena mezi více souborů. Při kompilaci jsou tyto části spojeny do jedné třídy.
Ukázka
Person.Part1.cs
public partial class Person{ public string FirstName { get; set; } public string LastName { get; set; }}
Person.Part2.cs
public partial class Person{ public string GetFullName() { return $"{FirstName} {LastName}"; }}