Konstruktory v C#
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Konstruktory v C#Konstruktory v C#

 

Konstruktory v C#

Google       Google       8. 4. 2008       76 168×

Určitě jste o nich už slyšeli, možná i víte k čemu jsou a jak fungují. V tomto článku si je ale rozebereme trochu podrobněji.

Dalo by se říct, že konstruktor je metoda, která se zavolá vždy, když dojde k vytvoření instance třídy nebo struktury. V tomto článku se ale nebudu konstruktory struktur vůbec zabývat (struktura je hodnotový typ, při zavolání implicitního konstruktoru tak vznikne instance s vynulovanými datovými členy). Konstruktor může například nastavovat nějaké výchozí hodnoty, nebo je dostat jako parametr při vytváření instance třídy (pak mluvíme o parametrickém konstruktoru).

Základní konstruktor

public class MojeTřída
{
    public MojeTřída()
    {
        // Toto je tělo konstruktoru.

    }
    // Zbytek třídy bude tady
}

Zatím je to nemastné neslané, máme třídu a v ní konstruktor, který nic nedělá. Jen si všimněte základního poznávacího prvku konstruktoru – musí se jmenovat naprosto stejně jako jeho třída. Jak už bylo několikrát zmíněno, k zavolání konstruktoru dojde při vytvoření instance třídy, tedy například takhle:

MojeTřída třída = new MojeTřída();

Přetěžování konstruktorů

C# podporuje tzv. přetěžování konstruktorů. To znamená, že konstruktorů jedné třídy máme víc, jen s jinými parametry. Naše třída MojeTřída se třemi konstruktory by vypadala takto:

public class MojeTřída
{
    public MojeTřída()
    {
        // Bezparametrický konstruktor

        // První konstruktor

    }

    public MojeTřída(int Věk)
    {
        // Konstruktor s jedním parametrem

        // Druhý konstruktor
    }

    public MojeTřída(int Věk, string Jméno)
    {
        // Konstruktor se dvěma parametry

        // Třetí konstruktor
    }
    // Zbytek třídy bude tady

}

Kompilátor si už sám vybere ten správný konstruktor podle parametrů, které zadáme instanci třídy. Opět si to ukážeme na příkladu.

MojeTřída třída1 = new MojeTřída();
 // Použije se první, bezparametrický konstruktor

MojeTřída třída2 = new MojeTřída(20,"Honza");
// Tentokrát se použije třetí konstruktor
// přijímající dva parametry

MojeTřída třída3 = new MojeTřída("Honza");
// Při pokusu o zkompilování vyhodí chybu - 
// nedefinovali jsme žádný konstruktor, který
// by přijímal jeden parametr typu string

Volání konstruktoru z jiného konstruktoru

C# nám umožňuje zavolat jeden konstruktor z jiného. Řekl bych, že příklad mluví za vše.

public class MojeTřída
{
    public MojeTřída()
        : this(10)
    {
        // Bezparametrický konstruktor

        // Pvní konstruktor

    }

    public MojeTřída(int Věk)
    {
        // Konstruktor s jedním parametrem

        // Druhý konstruktor

    }
}

Trošku blíž si popíšeme tuto část:

public MojeTřída(): this(10)

Klíčové slovo this klasicky odkazuje na třídu, se kterou zrovna pracujeme. Nejinak je tomu tady. Když řekneme this(10), ve skutečnosti tím chceme zavolat metodu public MojeTřída(int Věk). Způsob, který jsme si právě předvedli, se nazývá inicializátor.

Další důležitou věcí je pořadí volání jednotlivých metod (konstruktorů), když využijeme inicializátor. Pokud vytvoříme instanci naší třídy s bezparametrickým konstruktorem, pak se nejdřív zavolá druhý konstruktor (ten s parametrem Věk). V C# nemůžeme explicitně zavolat konstruktor, jako je to možné například u metod, například že bychom napsali MojeTrida(20);. Jediný způsob jak zavolat konstruktor z konstruktoru tak zůstává zmíněná metoda přes inicializátor.

Malá poznámka na závěr: Jediná povolená klíčová slova v inicializátoru jsou this a base (to probereme v další kapitolce).

Konstruktory při dědění

Pro začátek si vytvoříme jednoduchou „třídovou“ konstrukci, ve které vytvoříme dceřinou třídu od třídy MojeBázováTřída.

public class MojeBázováTřída
{
    public MojeBázováTřída()
    {
        // První konstruktor bázové třídy

    }

    public MojeBázováTřída(int Věk)
    {
        // Druhý konstruktor bázové třídy

    }
}

public class MojeZděděnáTřída : MojeBázováTřída
// Zde dochází k dědění
{
    public MojeZděděnáTřída()
    {
        // První konstruktor zděděné třídy

    }

    public MojeZděděnáTřída(int Věk)
        : base(Věk)
    {
        // Druhý konstruktor zděděné třídy

    }
}

Na výše uvedeném kódu není nic k nepochopení, ale jaké bude pořadí volání konstruktorů při vytvoření instance odvozené třídy? Jak mnozí už určitě tušíte, nejdříve se zavolá konstruktor bázové třídy a až po něm konstruktor jejího potomka (tedy odvozené třídy). Z toho tedy vyplývá, že kód konstruktoru bázové třídy se vykoná, i když ho explicitně nezavoláme (což ani nemůžeme) nebo i když nepoužijeme klíčové slovo base. Nelekejte se, to je naprosto normální chování konstruktorů při využití dědičnosti.

Privátní konstruktory

Privátní (soukromé) konstruktory, označené klíčovým slovem private, jsou trochu zvláštní skupinou, proto jim budu věnovat kousek článku. Je to kvůli tomu, že nemůžeme vytvářet instance nebo dědit od třídy, která má pouze privátní konstruktory. K čemu by nám taková třída byla? Téměř k ničemu, snad jen kdybychom ji nacpali statickými členy (opak instančního členu, který je vázán na instanci třídy, statický člen popisuje třídu jako takovou), tudíž bychom nechtěli vytvářet její instance. Můžeme ale mít vedle sebe jak soukromé, tak veřejné konstruktory (public). Vtip je v tom, že veřejný konstruktor se může pomocí nějakého zřetězení dostat do konstruktoru privátního, protože členy označené klíčovým slovem private jsou přeci dostupné zevnitř třídy. Pro lepší pochopení si to znovu ukážeme na příkladu:

public class MojeTřída
{
    private MojeTřída()
    {
        Console.WriteLine("Toto je bezparametrický konstruktor (kl. slovo private!)");
    }

    public MojeTřída(int var)
        : this()
    {
        Console.WriteLine("Toto je konstruktor s jedním parametrem (kl. slovo public)");
    }
}

Pokud uděláme instanci třídy MojeTřída pomocí tohoto kódu:

MojeTřída obj = new MojeTřída(10);

vše bude fungovat jak má, i když se pomocí klíčového slova this odkazuje na privátní konstruktor. Kdybychom ale zkusili vytvořit instanci bez parametru, kompilace by skončila s chybovým hlášením 'Konstruktory.MojeTřída.MojeTřída()' is inaccessible due to its protection level. Tato hláška říká, že náš konstruktor je nepřístupný kvůli jeho přístupovému modifikátoru. Máme tedy před sebou jasný důkaz toho, že privátní členy jsou přístupné jen zevnitř třídy.

Můžeme vytvořit třídu, která bude mít jen privátní konstruktory, ale jak už jsem se zmínil, taková třída nebude děditelná, ani nebudeme moci vytvářet její instance.

To jsme probrali dědění, privátní konstruktory i nějaké obyčejné konstruktory. Co nám ještě zbývá? Dnes se podíváme už jen na statické konstruktory.

Statické konstruktory

Statické konstruktory jsou novinkou až v C# (tím myslím, že nebyly v C++, nevím, jak jsou na tom ostatní jazyky). Zajímavostí tohoto typu konstruktorů je to, že dojde k jeho zavolání ještě před vytvořením první instance třídy. Nemůžeme přesně říct, kdy dojde k zavolání; jediné, co víme jistě, je, že to bude ještě před instancí. Syntaxe je opět velmi jednoduchá, jen přidáme slůvko static.

public class MojeTřída
{
    static MojeTřída()
    {
        // Tělo konstruktoru
        // Může přistupovat jen ke statickým členům!

    }
}

Základní charakteristiky statických konstruktorů si shrneme ve čtyřech bodech:

  1. V jedné třídě může být právě jeden statický konstruktor
  2. Takový konstruktor by měl být bezparametrický.
  3. Může přistupovat pouze ke statickým členům třídy.
  4. V hlavičce statického konstruktoru by neměl být žádný přístupový modifikátor.

Na statických konstruktorech toho mnoho zajímavého už nevykoukáme, takže je čas na nějaký příklad.

public class MojeTřída
{
    static string jméno;
    static MojeTřída()
    {
        jméno = "Honza";
    }
}

Pokud zkusíte přečíst obsah proměnné jméno, klidně i před vytvořením instance třídy, bude v ní uloženo slovo Honza. A to proto, že došlo k zavolání konstruktoru hned, co se procesor dozvěděl, že máme s třídou něco v úmyslu.

FAQ

Na závěr dnešního článku si uvedeme takový krátký FAQ – často kladené otázky.

Co se stane, když nedefinuji žádný konstruktor?

Pokud programátor nedefinuje žádný explicitní konstruktor, kompilátor automaticky použije svůj bezparametrický. Pokud ale definujete třeba jen jeden konstruktor, potlačíte tím toto chování kompilátoru.

Co když budu mít konstruktor pro MojeZděděnáTřída, ale ne pro MojeBázováTřída?

Situace je podobná té výše, aplikace se bez potíží zkompiluje, kompilátor vygeneruje bezparametrický konstruktor pro bázovou třídu.

Může ne-statický konstruktor přistupovat ke statickým členům?

Ano, může, bez jakýchkoliv komplikací. Trošku přísnější jsou statické konstruktory, které mohou přistupovat jen ke statickým členům.

To je pro dnešek vše. Doufám, že vám článek řekl něco nového o světě konstruktorů v jazyce C#.

Zdroj: http://www.codeproject.com/KB/dotnet/ConstructorsInCSharp.aspx

×Odeslání článku na tvůj Kindle

Zadej svůj Kindle e-mail a my ti pošleme článek na tvůj Kindle.
Musíš mít povolený příjem obsahu do svého Kindle z naší e-mailové adresy kindle@programujte.com.

E-mailová adresa (např. novak@kindle.com):

TIP: Pokud chceš dostávat naše články každé ráno do svého Kindle, koukni do sekce Články do Kindle.

Hlasování bylo ukončeno    
0 hlasů
Google
Jakub studuje informatiku na FIT ČVUT, jeho oblíbenou platformou je .NET.
Web     Twitter     Facebook     LinkedIn    

Nové články

Obrázek ke článku Stavebnice umělé inteligence 1

Stavebnice umělé inteligence 1

Článek popisuje první část stavebnice umělé inteligence. Obsahuje lineární a plošnou optimalizaci.  Demo verzi je možné použít pro výuku i zájmovou činnost. Profesionální verze je určena pro vývojáře, kteří chtějí integrovat popsané moduly do svých systémů.

Obrázek ke článku Hybridní inteligentní systémy 2

Hybridní inteligentní systémy 2

V technické praxi využíváme často kombinaci různých disciplín umělé inteligence a klasických výpočtů. Takovým systémům říkáme hybridní systémy. V tomto článku se zmíním o určitém typu hybridního systému, který je užitečný ve velmi složitých výrobních procesech.

Obrázek ke článku Jak vést kvalitně tým v IT oboru: Naprogramujte si ty správné manažerské kvality

Jak vést kvalitně tým v IT oboru: Naprogramujte si ty správné manažerské kvality

Vedení týmu v oboru informačních technologií se nijak zvlášť neliší od jiných oborů. Přesto však IT manažeři čelí výzvě v podobě velmi rychlého rozvoje a tím i rostoucími nároky na své lidi. Udržet pozornost, motivaci a efektivitu týmu vyžaduje opravdu pevné manažerské základy a zároveň otevřenost a flexibilitu pro stále nové výzvy.

Obrázek ke článku Síla týmů se na home office může vytrácet. Odborníci radí, jak z pracovních omezení vytěžit maximum

Síla týmů se na home office může vytrácet. Odborníci radí, jak z pracovních omezení vytěžit maximum

Za poslední rok se podoba práce zaměstnanců změnila k nepoznání. Především plošné zavedení home office, které mělo být zpočátku jen dočasným opatřením, je pro mnohé už více než rok každodenní realitou. Co ale dělat, když se při práci z domova ztrácí motivace, zaměstnanci přestávají komunikovat a dříve fungující tým se rozpadá na skupinu solitérů? Odborníci na personalistiku dali dohromady několik rad, jak udržet tým v chodu, i když pracovní podmínky nejsou ideální.

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý