7. Konstruktory

7.2. Vlastní konstruktor

V minulém případě implicitního konstruktoru jste asi vnímali, že by bylo vhodné si vytvořit vlastní konstruktor, kterému mu předáme skutečné parametry a těmi naplníme jednotlivé datové složky vytvářené instance. K jednotlivým datovým složkám třídy a zároveň k jejím metodám  přistupujeme pomocí tečkové notace (anglicky „Dot Notation“). Pomocí klíčového slova this přistupujeme do obsahu třídy. 

Syntaxe volání vlastního konstruktoru vypadá následovně:

new identifikátorTřídy(skutečnéParametry)

kde:

  • identifikátorTřídy - název třídy, podle které bude generována instance
  • skutečnéParametry - uvádění skutečných parametrů není povinné (konstruktor nemusí přijímat žádné parametry, záleží na nás, jak budeme specifikovat vlastní konstruktor). Hodnotou takového výrazu konstruktoru je odkaz na vytvořenou instanci třídy. Implicitní ani vlastní konstruktory se nedědí.


Ilustrativní příklad AutoVlastniKonstruktor
Program AutoVlastniKonstruktor
  • Popis: Vytvoření instance třídy pomocí vlastního konstruktoru, inicializace datových složek třídy
  • Zadání: Vytvořte novou instanci třídy autoOctavia předchozí nestatické třídy Auto pomocí vlastního konstruktoru. Konstruktor bude přijímat jako formální parametry kapacitaNadrze, stavNadrze, spotreba (datové typy těchto parametrů jsou shodné s datovými typy datových složek třídy Auto). Nastavte délku grafického ukazatele paliva (nádrž je plná) na 20 znaků. Počáteční stav najetých km (ujetoKm) je 0. V hlavní metodě vytvořte instanci třídy Auto s názvem autoOctavia se skutečnými parametry 55, 50, 0 (kapacitaNadrze, stavNadrze, spotreba). Vypište v Main kapacitu nádrže, stav ujetých km, objem nádrže a zobrazte objem nádrže pomocí grafického prvku. Ujeďte s autem 100 km a proveďte znovu všechny výpisy
  • Řešení: Auto_Main 
    (spojení programů AutoNestatickeDatoveSlozky + AutoStatickaDatovaSlozka + AutoUjedTrasu + AutoVlastniKonstruktor)


V konstruktoru nazvaným stejným jménem jako třída, tedy Auto, jsme využili formální parametry pro inicializaci datových složek. První parametr kapacitaNadrze je určen k definování skutečného objemu nádrže auta. Výchozí kapacitu nádrže jsme již dříve inicializovali přímo v deklaraci této datové složky (přiřadili jsme jí hodnotu 60 litrů). Každé auto však bude mít jinou kapacitu nádrže, proto tato datová složka má modifikátor přístupu typu readonly, takže ji lze přiřadit jinou hodnotu v konstruktoru, což právě provedeme pomocí hodnoty ve formálním parametru kapacitaNadrze. Dalším formálním parametrem stavNadrze jsme nastavili objem paliva v nádrži auta. Jako poslední jsme použili parametr spotreba a tím jsme nastavili deklarovanou spotřebu litrů paliva na 100 km jízdy autem. 

//Deklarace vlastního konstruktoru třídy
public Auto(double kapacitaNadrze, double stavNadrze, double spotreba)
{
    //Inicializace soukromých datových složek
    this.stavNadrze = stavNadrze;
    this.ujetoKm = 0;
    this.spotreba = spotreba;
    //Inicializace statické datové složky
    delkaGrafUkazatele = 20;
    //Inicilazace datové složky (readonly) pomocí parametru
    this.kapacitaNadrze = kapacitaNadrze;
}

Kód 1: Příklad deklarace vlastního konstruktoru třídy Auto

Pokud v kódu používáme stejný název parametru, jako je název datové složky, nelze vynechat klíčové slovo this – viz Kód 2. Kompilátor oznámí: Přiřazení proběhlo u stejné proměnné. Kompilátor totiž neví, že identifikátor vlevo od přiřazení byl zamýšlen jako datová složka a vpravo jako hodnota parametru. Formální parametr se stejným názvem jako datová složka totiž skryje datovou složku uváděnou v příkazech metody (je upřednostněn formální parametr – lokálnost). 

/*Inicilazace datové složky (readonly) pomocí parametru
 * s vynecháním this. Kompilátor neví, že se jedná o přiřazení
 * hodnoty parametru do datové složky -> K.O. */
kapacitaNadrze = kapacitaNadrze;

Kód 2: Příklad důsledku nepoužití klíčového slova this při stejném názvu datové složky a formálního parametru

V následujícím kódu je volán vlastní konstruktor Auto třídy Auto, kterému jsou předány skutečné parametry 55, 50, 5, jejichž hodnota je přiřazena do příslušných datových složek (kapacitaNadrze, stavNadrze, spotreba). Pomocí klíčového slova new je vytvořena instance třídy, která je přiřazena objektu autoOctavia třídy Auto. Po proběhnutí těla konstruktoru tedy náš objekt autoOctavia nebude mít kapacitu nádrže 60 litrů, ale jen 55 litrů. Dále jsme nastavili objem nádrže na 50 litrů a definovali spotřebu 5 litrů paliva na 100 km – viz Kód 3. 

//Deklarace hlavní metody
static void Main(string[] args)
{
    /*Vytvoření instance třídy Auto pomocí volání vlastního konstruktoru
     * včetně předání skutečného parametru*/
    Auto autoOctavia = new Auto(55, 50, 5);
    Console.WriteLine("Kapacita nádrže: {0}", autoOctavia.kapacitaNadrze);
    Console.WriteLine("Ujeto km: {0}", autoOctavia.ujetoKm);
    Console.WriteLine("Stav nádrže: {0}", autoOctavia.stavNadrze);
    Console.WriteLine("Stav nádrže: {0}", autoOctavia.StavNadrzeGraficky());
    autoOctavia.UjedTrasu(100);
    Console.WriteLine("Auto Octavia:");
    Console.WriteLine("Ujeto km: {0}", autoOctavia.ujetoKm);
    Console.WriteLine("Stav nádrže: {0}", autoOctavia.stavNadrze);
    Console.WriteLine("Stav nádrže: {0}", autoOctavia.StavNadrzeGraficky());
    //Čekání na stisk klávesy -> ukončení programu
    Console.ReadKey();
}

Kód 3: Deklarace hlavní metody třídy Auto - vytvoření instance autoOctavia a výpis hodnot datových složek

V následujícím výpisu v konzole vidíme stav autoOctavia před jízdou a po ujetí 100 km - viz Výstup programu - Kód Auto_Main. 

Kapacita nádrže: 55
Ujeto km: 0
Stav nádrže: 50
Stav nádrže: [##################  ]
Auto Octavia:
Ujeto km: 100
Stav nádrže: 45
Stav nádrže: [################    ]

Výstup programu - Kód Auto_Main