Algoritmy a programování III

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})");
}

Parametry typu

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.

Základní třídy

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 Pointzákladní třída .Point3D Z prvního příkladu je objectzá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 Pointa každá Point3D instance obsahuje tři vlastnosti, XYZ.

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 PointPoint3Dna :


Point a = new(10, 20);
Point b = new Point3D(10, 20, 30);

Struktury

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);
}