Týden 5
Organizační bloky, třídy a objekty
Třídy jsou nejzákladnějšími typy jazyka C#. Třída je datová struktura, která kombinuje stav (pole) a akce (metody a další členy funkce) v jedné jednotce. Třída poskytuje definici pro instance třídy, označované také jako objekty. Třídy podporují dědičnost a polymorfismus, mechanismy, kterými mohou odvozené třídy rozšířit a specializovat základní třídy.
Nové třídy se vytvářejí pomocí deklarací tříd. Deklarace třídy začíná záhlavím. Hlavička určuje:
- Atributy a modifikátory třídy
- Název třídy
- Základní třída (při dědění ze základní třídy)
- Rozhraní implementované třídou.
Za hlavičkou následuje tělo třídy, které se skládá ze seznamu deklarací členů zapsaných mezi oddělovači {
a }
.
Následující kód zobrazuje deklaraci jednoduché třídy s názvem Point
:
(X, Y) = (x, y);
}
" style="box-sizing: inherit; outline-color: inherit; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 1em; direction: ltr; border: 0px; padding: 0px; line-height: 1.3571; display: block; position: relative;">public class Point
{
public int X { get; }
public int Y { get; }
public Point(int x, int y) => (X, Y) = (x, y);
}
Instance tříd jsou vytvořeny pomocí operátoru new
, který přiděluje paměť nové instanci, vyvolá konstruktor pro inicializaci instance a vrátí odkaz na instanci. Následující příkazy vytvoří dva Point
objekty a uloží odkazy na tyto objekty ve dvou proměnných:
var p1 = new Point(0, 0);
var p2 = new Point(10, 20);
Paměť zabíraná objektem je automaticky uvolněna, když objekt již není dostupný. Není nutné ani není možné explicitně uvolnit objekty v jazyce C#.
var p1 = new Point(0, 0);
var p2 = new Point(10, 20);
Aplikace nebo testy pro algoritmy mohou vyžadovat vytvoření více Point
objektů. Následující třída vygeneruje sekvenci náhodných bodů. Počet bodů je nastaven primárním parametrem konstruktoru . Primární parametr numPoints
konstruktoru je v oboru pro všechny členy třídy:
CreatePoints()
{
var generator = new Random();
for (int i = 0; i < numberOfPoints; i++)
{
yield return new Point(generator.Next(), generator.Next());
}
}
}
" style="box-sizing: inherit; outline-color: inherit; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 1em; direction: ltr; border: 0px; padding: 0px; line-height: 1.3571; display: block; position: relative;">public class PointFactory(int numberOfPoints)
{
public IEnumerable<Point> CreatePoints()
{
var generator = new Random();
for (int i = 0; i < numberOfPoints; i++)
{
yield return new Point(generator.Next(), generator.Next());
}
}
}
Můžete použít třídu, jak je znázorněno v následujícím kódu:
var factory = new PointFactory(10);
foreach (var point in factory.CreatePoints())
{
Console.WriteLine($"({point.X}, {point.Y})");
}
Obecné třídy definují parametry typu. Parametry typu jsou seznam názvů parametrů typu uzavřených v šikmých závorkách. Parametry typu se řídí názvem třídy. Parametry typu pak lze použít v těle deklarací třídy k definování členů třídy. V následujícím příkladu jsou TFirst
parametry Pair
typu a TSecond
:
{
public TFirst First { get; }
public TSecond Second { get; }
public Pair(TFirst first, TSecond second) =>
(First, Second) = (first, second);
}
" style="box-sizing: inherit; outline-color: inherit; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 1em; direction: ltr; border: 0px; padding: 0px; line-height: 1.3571; display: block; position: relative;">public class Pair<TFirst, TSecond>
{
public TFirst First { get; }
public TSecond Second { get; }
public Pair(TFirst first, TSecond second) =>
(First, Second) = (first, second);
}
Typ třídy, který je deklarován k převzetí parametrů typu, se nazývá obecný typ třídy. Typy struktur, rozhraní a delegátů můžou být také obecné. Při použití obecné třídy musí být pro každý z parametrů typu zadány argumenty typu:
(1, "two");
int i = pair.First; //TFirst int
string s = pair.Second; //TSecond string
" style="box-sizing: inherit; outline-color: inherit; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 1em; direction: ltr; border: 0px; padding: 0px; line-height: 1.3571; display: block; position: relative;">var pair = new Pair<int, string>(1, "two");
int i = pair.First; //TFirst int
string s = pair.Second; //TSecond string
Obecný typ se zadanými argumenty typu, jako Pair<int,string>
je výše, se nazývá konstruovaný typ.
Deklarace třídy může určit základní třídu. Postupujte podle parametrů názvu třídy a zadejte dvojtečku a název základní třídy. Vynechání specifikace základní třídy je stejné jako odvození z typu object
. V následujícím příkladu je Point
základní třída .Point3D
Z prvního příkladu je object
základní třída :Point
public class Point3D : Point
{
public int Z { get; set; }
public Point3D(int x, int y, int z) : base(x, y)
{
Z = z;
}
}
Třída dědí členy své základní třídy. Dědičnost znamená, že třída implicitně obsahuje téměř všechny členy své základní třídy. Třída nedědí instance a statické konstruktory a finalizátor. Odvozená třída může přidat nové členy k členům, které dědí, ale nemůže odebrat definici zděděného člena. V předchozím příkladu Point3D
dědí X
členy a Y
z Point
a každá Point3D
instance obsahuje tři vlastnosti, X
, Y
a Z
.
Existuje implicitní převod z typu třídy na kterýkoli z jejích základních typů tříd. Proměnná typu třídy může odkazovat na instanci této třídy nebo na instanci jakékoli odvozené třídy. Například u předchozích deklarací třídy může proměnná typu Point
odkazovat na nebo Point
Point3D
na :
Point a = new(10, 20);
Point b = new Point3D(10, 20, 30);
Třídy definují typy, které podporují dědičnost a polymorfismus. Umožňují vytvářet sofistikované chování založené na hierarchiích odvozených tříd. Naproti tomu typy struktur jsou jednodušší typy, jejichž primárním účelem je ukládání datových hodnot. Struktury nemohou deklarovat základní typ; implicitně odvozují od System.ValueType. Z typu nemůžete odvodit jiné struct
typy struct
. Jsou implicitně zapečetěné.
(X, Y) = (x, y);
}
" style="box-sizing: inherit; outline-color: inherit; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 1em; direction: ltr; border: 0px; padding: 0px; line-height: 1.3571; display: block; position: relative;">public struct Point
{
public double X { get; }
public double Y { get; }
public Point(double x, double y) => (X, Y) = (x, y);
}