Vytvárame prvé triedy

<< Textové súbory | Obsah | Vytvárame funkčné triedy >>

Predstavte si, že si chcete vytvoriť program na pohodlné vyhľadávanie vo vašej zbierke DVD filmov. O každom DVD viete:

  • názov filmu
  • hercov, ktorý v ňom hrali
  • žánre do ktorých spadá, predpokladáme že film môže mať viac žánrov (napr. "kriminálka a thriller" alebo "romantika, komédia a rodinný")
  • dĺžku filmu
  • vaše hodnotenie kvality filmu na stupnici od nula do desať.

Chceli by ste, aby váš program vedel:

  • vložiť nové DVD
  • vymazať DVD (napríklad sa poškodilo alebo stratilo)
  • vypísať všetky filmy vo vašej zbierke
  • vypísať tie filmy, ktoré zodpovedajú danému žánru (napr. komédie)
  • vypísať tie filmy, ktoré sa dajú pozrieť do nejakého času (napr. < 90 minút)
  • vypísať všetkých filmy, kde hral daný herec
  • vypísať filmy, ktoré sú podľa vášho hodnotenia na stupnici od 7 do 10.

Všimnite si dobre toto zadanie. Ako snáď pri všetkých programoch aj pri tomto si potrebujeme identifikovať dve základné množiny požiadaviek:

  • s akými dátami bude náš program pracovať
  • aké služby má poskytovať resp. akú funkcionalitu má mať.

Tieto dve množiny požiadaviek sú úplne kľúčové. Pokiaľ si ich programátor neuvedomí, nemal by začať písať ani riadok kódu. Objektovo orientované programovanie zachováva tento princíp rozdelenia na dáta a funkcionalitu nie len pre celý program, ale aj pre jeho základné "súčiastky" - triedy a objekty.

V prvej polovici tejto prednášky sa budeme zaoberať prvou množinou požiadaviek - dátami

Trieda ako obal pre viac premenných

Keď máme ujasnenú prvú množinu požiadaviek, teda s akými dátami bude program pracovať, nasleduje prirodzene druhá otázka: "V akých štruktúrach to budem uchovávať?" Jednotlivé časti informácií by ste už asi vedeli uložiť vo vhodných premenných.

  • Názov filmu bude zrejme String,
  • meno jedného herca bude tiež typu String, keďže tých hercov je v jednom filme viac, asi by ste ich ukladali do poľa Stringov,
  • jeden žáner budeme reprezentovať tiež ako String, a keďže tých žánrov v jednom filme môže byť viac, asi by ste ich tiež ukladali do poľa Stringov,
  • dĺžku filmu uložíme asi do premennej typu int,
  • a hodnotenie môže byť reprezentované napríklad premennou typu double.

Dvdčkám by sme vedeli vymyslieť aj ďalšie vlastnosti ako tvar, farba, hmotnosť, cena a podobne. Tieto vlastnosti však nie je potrebné uvažovať, keďže s týmito informáciami podľa zadania zjavne nepotrebujeme pracovať. Zapamätajme si, že uchovávame iba užitočné vlastnosti, teda také, ktoré potrebujeme na zabezpečenie požadovanej funkcionality.

Keďže ideme pracovať s potenciálne veľkým počtom DVD nosičov, je vhodné, aby sme vedeli nejako povedať, že jedna sada týchto premenných patrí jednému DVD a iná sada inému DVD. Chceme teda nejako reprezentovať to, že jedno DVD si bude o sebe pamätať názov filmu, hercov, žánre, dĺžku filmu a hodnotenie.

S podobnou situáciou sme sa už stretli. Keď sme chceli aby si kresliaca plocha pamätala veľa korytnačiek, rozšírili sme triedu WinPane a zadefinovali si v tejto novej triede inštančnú premennú referencujúcu pole korytnačiek. Keď sme chceli, aby si plocha pamätala dvojrozmerné pole pre piškôrky, opäť sme nejako rozšírili WinPane.

V prípade DVD je neprirodzené rozširovať napríklad WinPane na DVDPlochu alebo Turtle na DVDKorytnačku, ktorá by predstavovala jedno DVD, lebo v prípade DVD nepotrebujeme pôvodné vlastnosti plochy či korytnačky.

V jave, keď chceme nejakú triedu vybudovať úplne od začiatku vytvárame rozšírenie triedy Object, ktorá je najoklieštenejšou triedou v jave. Napríklad aj pôvodná trieda Turtle a WinPane boli vytvorené rozšírením triedy Object, pretože všetky triedy sú vytvárané buď rozšírením triedy Object alebo rozšírením tried, ktorých pôvod má tiež korene v triede Object.

Vytvorme si triedu Dvd, ktorá obaľuje všetky premenné, ktoré potrebujeme na uchovanie informácií o jednom DVD.

public class Dvd extends Object {
  private String   nazovFilmu;
  private String[] herci;
  private String[] zanre;
  private int      dlzkaFilmu;
  private double   hodnotenie;
}

Ak vytvárame triedu ako rozšírenie triedy Object, nemusíme to expliticne písať. Nasledujúci zápis teda vyjadruje to isté ako predchádzajúci.

public class Dvd {
  private String   nazovFilmu;
  private String[] herci;
  private String[] zanre;
  private int      dlzkaFilmu;
  private double   hodnotenie;
}

Už vieme že tieto premenné, ktoré sú definované v triede, ale nie v jej metódach, sa nazývajú inštančné premenné.

Keď už máme vytvorenú triedu Dvd môžeme si vytvárať premenné typu Dvd podobne, ako sme si vytvárali nové korytnačky:

public class SkusanieDvd {
  public static void main(String[] args) {
    Dvd matrix = new Dvd();
    Dvd shawshank = new Dvd();
    ...
  }
}

Priamy prístup k inštančným premenným objektov

Teraz by sme potrebovali o každom z týchto filmov uložiť informácie, ktoré si o filmoch chceme ukladať - teda názov filmu, hercov, žánre, dĺžku filmu a hodnotenie. Chceme teda naplniť inštančné premenné vytvorených objektov typu Dvd.

Jeden zo spôsobov prístupu k inštančným premenným, a zároveň aj najmenej odporúčaný, je priamy prístup z vonku cez premennú objektu. Na to aby sme to umožnili, musíme im vymazať príznak private.

Budeme používať "bodkovú" notáciu. Podobne, ako keď voláme metódy na objektoch, môžeme za istých okolností (určite nesmú byť private) pristupovať cez bodku aj k inštančným premenným objektov.

public class SkusanieDvd {
  public static void main(String[] args) {
    Dvd matrix = new Dvd();
    ...
    matrix.nazovFilmu = "The Matrix";
    matrix.herci = new String[3]; // inštančná premenná herci mala zatiaľ v sebe null
    matrix.herci[0] = "Keanu Reeves";
    matrix.herci[1] = "Laurence Fishburne";
    matrix.herci[2] = "Carrie-Anne Moss";
    matrix.zanre = new String[2]; // inštančná premenná zanre mala zatiaľ v sebe null
    matrix.zanre[0] = "Akčný";
    matrix.zanre[1] = "Sci-Fi";
    matrix.dlzkaFilmu = 136;
    matrix.hodnotenie = 8.7;
    ...
    System.out.println("Dĺžka filmu " + matrix.nazovFilmu + " je " + matrix.dlzkaFilmu+ " minút");
    ...
  }
}
Dĺžka filmu The Matrix je 136 minút

Použitie getterov a setterov

Predchádzajúci spôsob nie je odporúčaný, lebo porušuje princíp zapúzdrenosti, v ktorom sa objekty autonómne starajú o hodnoty svojich vlastných inštančných premenných. Pri priamom prístupe si objekty nevedia samy ochrániť hodnoty svojich inštančných premenných, čo môže ohroziť očakávanú funkcionalitu ďalších metód.

Povedzme, že naša trieda Dvd, by mala metódu, ktorá pri výpise informácií o filme bude kresliť graficky ohodnotenie filmu napríklad počtom hviezdičiek. Keďže vieme, že hodnotenia sú v škále 0 až 10, prispôsobíme tomu veľkosť hviezdičiek a ich umiestnenie na ploche. A teraz si predstavte, že pri pridávaní nového filmu sa používateľ vášho programu preklepne a zadá namiesto desiatich sto hviezdičiek, alebo nejaký záporný počet.

Veľmi elegantne sa dá takéto prípady ošetriť tak, že hodnotu budeme nastavovať pomocou nastavovacej medódy - setter-a (z angličtiny setter = nastavovač, ale slovenský ekvivalent nikto nepoužíva). V tejto metóde si môžeme ošetriť správnosť nastavovanej hodnoty.

public class Dvd {
  String   nazovFilmu;
  String[] herci;
  String[] zanre;
  int      dlzkaFilmu;
  double   hodnotenie;
  ...
  void setHodnotenie(double hodnotenie) {
    if (hodnotenie < 0 || hodnotenie > 10) {
      System.err.println("Hodnotenie " + hodnotenie + " je mimo povolený rozsah [0,10]");
    }
    else {
      this.hodnotenie = hodnotenie;
    }
  }
  ...
}

Potom keď napíšeme nasledujúci príkaz, hodnotenie nám nedovolí zmeniť:

matrix.setHodnotenie(20.0); // hodnotenie sa nezmení
Hodnotenie 20.0 je mimo povolený rozsah [0,10]

Ochrana však v tomto prípade nie je dokonalá, lebo stále je možné meniť hodnotu priamo. Aby sme tomu zabránili, môžeme premennú hodnotenie nastaviť ako súkromnú napísaním slovíčka private pred jej deklaráciu.

public class Dvd {
  ...
  private double   hodnotenie;
  ...
}

Teraz keby sme chceli zmeniť hodnotu z vonku priamo, nedovolilo by nám to. Eclipse nám nasledujúci riadok podčiarkne červenou čiarou s chybou "The field Dvd.hodnotenie is not visible"

matrix.hodnotenie = 5.0;

Súkromné premenné môžu vidieť iba metódy v danej triede. Po nastavení hodnotenia, ako súkromnej premennej, nám teda nedovolí ani jej čítanie z vonku:

System.out.println("Hodnotenie je: " + matrix.hodnotenie); //Eclipse vypisuje chybu "The field Dvd.hodnotenie is not visible"

Na čítanie použijeme teda ďalšiu metódu vo vnútri triedy a to takzvaný getter (z angličtiny "getter" = odovzdávač, opäť slovenský ekvivalent nik nepoužíva).

public class Dvd {
  ...
  private double   hodnotenie;
  ...
  double getHodnotenie() {
    return hodnotenie;
  }
}

Zavolanie tohto gettera je potom nasledovné:

System.out.println("Hodnotenie je: " + matrix.getHodnotenie());
Hodnotenie je 8.7

Systém getterov a setterov je veľmi často využívaný. Aby ste sa nebodaj neupísali k smrti, keď máte veľa inštančných premenných, Eclipse umožňuje gettery a settery vygenerovať cez menu Source -> Generate Getters and Setters, kde si môžete špecifikovať, pre ktoré inštančné premenné sa majú gettery a settery vygenerovať.

Našej triede Dvd budeme odteraz chrániť jej inštančné premenné:

public class Dvd {
  private String   nazovFilmu;
  private String[] herci;
  private String[] zanre;
  private int      dlzkaFilmu;
  private double   hodnotenie;

  String getNazovFilmu() {
    return nazovFilmu;
  }

  void setNazovFilmu(String nazovFilmu) {
    this.nazovFilmu = nazovFilmu;
  }

  String[] getHerci() {
    return herci;
  }

  void setHerci(String[] herci) {
    this.herci = herci;
  }

  String[] getZanre() {
    return zanre;
  }

  void setZanre(String[] zanre) {
    this.zanre = zanre;
  }

  int getDlzkaFilmu() {
    return dlzkaFilmu;
  }

  void setDlzkaFilmu(int dlzkaFilmu) {
    if (dlzkaFilmu <= 0) {
      System.err.println("Dĺžka filmu musí byť kladné číslo");
    }
    else {
      this.dlzkaFilmu = dlzkaFilmu;
    }
  }

  double getHodnotenie() {
    return hodnotenie;
  }

  void setHodnotenie(double hodnotenie) {
    if (hodnotenie < 0 || hodnotenie > 10) {
      System.err.println("Hodnotenie " + hodnotenie + " je mimo povolený rozsah [0,10]");
    }
    else {
      this.hodnotenie = hodnotenie;
    }
  }
}

Naplnenie nového objektu typu Dvd a jeho používanie može teraz prebiehať nasledovne:

public class SkusanieDvd {
  public static void main(String[] args) {
    ...
    Dvd shawshank = new Dvd();
    shawshank.setNazovFilmu("The Shawshank Redemption");
    shawshank.setHerci(new String[]{"Tim Robbins","Morgan Freeman"});
    shawshank.setZanre(new String[]{"Dráma"})
    shawshank.setDlzkaFilmu(142);
    shawshank.setHodnotenie(9.2);
    ...
    System.out.println("Dĺžka filmu " + shawshank.getNazovFilmu() + " je " + shawshank.getDlzkaFilmu());
    ...
  }
}
Dĺžka filmu The Shawshank Redemption je 142

Konštruktory

Napĺňanie inštančných premenných priamo pri vytváraní objektu nám umožňuje konštruktor. Konštruktor je špeciálny typ metódy, ktorá sa volá iba pri vytváraní (konštruovaní) nového objektu. Keď už objekt existuje, konštruktor preňho už nevoláme. Výsledkom zavolania konštruktora je nový objekt, ktorý môžeme typicky priradiť do nejakej premennej príslušného typu.

Volanie konštruktora sa nachádza za kľúčovým slovíčkom new. Konštruktor môže mať žiaden alebo viac parametrov.

Dvd matrix = new Dvd(); // voláme konštruktor bez parametrov
File adresar = new File("C:/Windows"); // voláme konštruktor s jedným parametrom
File subor = new File(adresar, "system.ini"); // voláme konštruktor s dvoma parametrami
Scanner sc = new Scanner(subor);// voláme konštruktor s jedným parametrom

Každá trieda má aspoň jeden konštruktor. Môže ich mať aj viac, ale musia sa líšiť počtom parametrov alebo typmi parametrov. Ak sa metódy alebo konštruktory volajú rovnako a líšia sa iba parametrami hovoríme o preťažovaní. V predchádzajúcom príklade sme volali až dva rôzne konštruktory triedy File, ktoré sa odlišovali počtom parametrov.

Ak v triede nie je napísaný žiaden koštruktor, použije sa skrytý, takzvaný implicitný konštruktor. Ide o koštruktor, ktorý nemá žiadne vstupné parametre, ani žiadne príkazy v tele. Prázdny konštruktor sa v prípade, že neexistujú iné konštruktory triedy, písať nemusí. POZOR! Ak existuje v triede nejaký konštruktor s parametrami, implicitný konštruktor sa automaticky nedoplní a ak ho chceme používať musíme si ho dopísať sami. Ak by sme chceli napísať prázdny konštruktor, vyzeral by takto:

public class Dvd {
  ...
  public Dvd() {
    //prázdny konštruktor
  }
  ...
}

Konštruktor je špeciálny typ metódy. Od normálnych metód sa líši nasledovne:

  • meno konštruktora musí byť rovnaké ako meno triedy - v našom prípade Dvd
  • nepíšeme mu návratový typ, teda hlavička konštruktora nezačína slovom void ani nejakým konkrétnym typom
  • telo konštruktora teda neobsahuje žiadne vrátenie hodnoty cez return.

Prvou úlohou každého, aj prázdneho, konštruktora je vytvoriť objekt, jeho inštančné premenné a naplniť inštančné premenné preddefinovanými hodnotami.

Preddefinovaná hodnota pre triedové premenné je null. Premenné primitívnych typov null obsahovať nemôžu, takže majú určené nasledovné hodnoty.

  • Všetky číselné primitívne typy majú preddefinovanú nulu
  • boolean premenné majú preddefinovaný false
  • char má preddefinovanú hodnotu '\u0000', ktorá je neviditeľným (NUL) znakom, ktorý sa v praxi nevyužíva.

V našom prípade, keď vytvoríme nový objekt triedy Dvd cez prázdny konštruktor, máme v premenných nazovFilmu, herci a zanre hodnotu null, v premennej dlzkaFilmu hodnotu 0 a v premennej hodnotenie hodnotu 0.0

Po vytvorení objektu môžeme konštruktor použiť na vhodnejšie nastavenie inštančných premenných. Využijeme na to niektorý konštruktor s parametrami.

public class Dvd {
  ...
  public Dvd(String nazovFilmu, String[] herci, String[] zanre, int dlzkaFilmu, double hodnotenie) { // tento konštruktor nám nastaví všetky inštančné premenné
    this.nazovFilmu = nazovFilmu;
    this.herci = herci;
    this.zanre = zanre;
    this.dlzkaFilmu = dlzkaFilmu;
    this.hodnotenie = hodnotenie;
  }

  public Dvd(String nazovFilmu, int dlzkaFilmu, double hodnotenie) { //nastavíme iba 3 inštančné premenné a zvyšok necháme na settery
    this.nazovFilmu = nazovFilmu;
    this.dlzkaFilmu = dlzkaFilmu;
    this.hodnotenie = hodnotenie;
  }

  public Dvd() {
    // doplníme prázdny konštruktor, aby sme mohli naďalej volať aj konštruktor bez parametrov aj keď sme vytvorili konštruktory s parametrami
  }
  ...
}

Nový objekt triedy DVD potom vytvoríme volaním ľubovoľného (preťaženého) konštruktora.

public class SkusanieDvd {
  public static void main(String[] args) {
    ...
    String[] herci = new String[3]; // vyrobíme si pomocnú lokálnu premennú
    herci[0] = "Eva Vejmělková";
    herci[1] = "Jiří Bábek";
    herci[2] = "Robo Grigorov";
    String[] zanre = new String[3]; // vyrobíme si pomocnú lokálnu premennú
    zanre[0] = "Dráma";
    zanre[1] = "Romantika";
    zanre[2] = "Muzikál";
    Dvd fontana = new Dvd("Fontána pre Zuzanu",herci,zanre,81,6.3); //vytvoríme nový objekt s pomocou konštruktora s piatimi parametrami

    Dvd pacho = new Dvd("Pacho, hybský zbojník",91,8.5); //ak použijeme konštruktor s troma parametrami, potrebujeme ešte nastaviť hercov a žánre
    herci = new String[2]; // vytvoríme nové pole do pomocnej premennej herci
    herci[0] = "Jozef Kroner";
    herci[1] = "Marián Labuda";
    pacho.setHerci(herci);
    zanre = new String[1]; // vytvoríme nové pole do pomocnej premennej zanre
    zanre[0] = "Komédia";
    pacho.setZanre(zanre);
    ...
    System.out.println("Herci vo filme " + fontana.getNazovFilmu() + " sú:");
    for (int i = 0; i < fontana.getHerci().length; i++) {
      System.out.println(fontana.getHerci()[i]);
    }
    ...
  }
}
Herci vo filme Fontána pre Zuzanu sú:
Eva Vejmělková
Jiří Bábek
Robo Grigorov

Ak by ste potrebovali, tak konštruktor bez parametrov nemusí byť vždy prázdny. Nasledujúci konštruktor nastaví automaticky hodnotenie 5.0 pre každý objekt triedy Dvd, ktorý bol vytvorený cez konštruktor bez parametrov.

POZOR! Do triedy môžeme napísať iba jeden konštruktor s rovnakým počtom, typmi a poradím typov parametrov. Takže nemôžete mať v triede aj prázdny konštruktor bez parametrov aj konštruktor bez parametrov, ktorý má v sebe nejaké príkazy.

public class Dvd {
  ...
  public Dvd() { //prednastavujeme filmom hodnotenie 5.0
    this.hodnotenie = 5.0;
  }
  ...
  public Dvd() { //tento konštruktor tu už byť nesmie
  }
}

Aj konštruktor sa bežne používa na ochranu hodnôt inštančných premenných. Prepíšeme si konštruktor na taký, ktorý robí rovnaké kontroly, ako sme písali v setteroch. V prípade, že vstupné hodnoty nebudú spĺňať požadované podmienky, nastavíme im nejaké preddefinované hodnoty.

public class Dvd {
  ...
  public Dvd(String nazovFilmu, String[] herci, String[] zanre, int dlzkaFilmu, double hodnotenie) { // tento konštruktor nám nastaví všetky inštančné premenné
    this.nazovFilmu = nazovFilmu;
    this.herci = herci;
    this.zanre = zanre;

    if (dlzkaFilmu <= 0) {
      this.dlzkaFilmu = 0; //preddefinovaná dĺžka bude nula
    }
    else {
      this.dlzkaFilmu = dlzkaFilmu;
    }

    if (hodnotenie < 0 || hodnotenie > 10) {
      this.hodnotenie = 5.0; //preddefinované hodnotenie bude 5.0
    }
    else {
      this.hodnotenie = hodnotenie;
    }
  }
...
}

Keďže aj konštruktor je riadny kus kódu, ktorý sa nám písať nechce, Eclipse prichádza s generátorom koštruktora. Koštruktor vygenerujete cez menu Source -> Generate Constructor using fields.

Hierarchia konštruktorov

V kapitolke o koštruktoroch sme povedali, že prvou úlohou každého konštruktora je vytvoriť objekt, jeho inštančné premenné a naplniť inštančné premenné prednastavenými hodnotami. Vytváranie objektu reálne vykonáva konštruktor triedy Object a inštančné premenné sa doplňujú postupne volaním viacerých konštruktorov. Ako to vlastne funguje?

Musíme si uvedomiť, že tým, že naša trieda rozširuje nejakú inú triedu, tak okrem nových vecí musí vedieť aj všetko to, čo pôvodná trieda. Z toho dôvodu sa ako prvá vec pri vytváraní nového objektu vyrobí objekt, ktorý vie všetko to, čo by mu umožnila pôvodná trieda a potom naňho nabalíme schopnosti, ktoré má od našej triedy.

Keďže všetky triedy pôvodne pochádzajú z triedy Object, tak každý nový objekt najprv vznikne ako inštancia, ktorá má všetky schopnosti, ktoré mu poskytuje trieda Object a až potom sa na tieto schopnosti nabaľujú schopnosti (inštančné premenné a metódy), ktoré poskytujú rozširujúce triedy.

Prvá vec, čo urobí každý konštruktor je, že zavolá konštruktor rodičovskej triedy (t.j. z triedy z ktorej sa rozširuje). Tento rodičovský konštruktor zavolá konštruktor svojho rodiča a tak ďalej až kým sa nedostaneme k zavolaniu konštruktora triedy Object.

Ak sa na začiatku konštruktora neuvedie volanie rodičovského konštruktora, toto volanie sa uskutočňuje automaticky. Automatické volanie používa rodičovský konštruktor bez parametrov.

Pozrime sa na to, čo sa deje v kóde. Rodičovská trieda sa v jave označuje slovom super. Keď si vygenerujete konštruktor cez generátor konštruktora v Eclipse, ako prvý príkaz v konštruktore je super();. Ak je tento príkaz uvedený, MUSÍ byť uvedený ako prvý príkaz v konštruktore. To je volanie rodičovského konštruktora - neznamená to, že rodičovská trieda sa volá super.

Ak nechcete aby sa volal konštruktor rodičovskej triedy bez parametrov, môžete zavolať ľubovoľný jeden konštruktor s parametrami z rodičovskej triedy.

Je potrebné dodať, že niekedy sa konštruktor bez parametrov volať nedá a musíme volať rodičovský konštruktor s parametrami cez super(...). Je to vtedy, keď rodičovská trieda takýto konštruktor nemá a zároveň má nejaký konštruktor s parametrami t.j. implicitný konštruktor sa jej automaticky nevygeneroval.

Použitie si ukážeme na triede DvdNaPredaj, ktorá rozširuje našu triedu Dvd pridaním ceny.

public class DvdNaPredaj extends Dvd {
  double cena;

  public DvdNaPredaj(String nazovFilmu, String[] herci, String[] zanre, int dlzkaFilmu, double hodnotenie, double cena) { // tento konštruktor nám nastaví všetky inštančné premenné
    super(nazovFilmu, herci, zanre, dlzkaFilmu, hodnotenie); // zavolanie konštruktora triedy Dvd s 5 parametrami
    this.cena = cena;
  }

  public DvdNaPredaj(String nazovFilmu, double cena) { //nastavíme iba 2 inštančné premenné
    super(); //použijeme rodičovský konštruktor bez parametrov- tento riadok môžeme vymazať a bude to fungovať rovnako
    this.nazovFilmu = nazovFilmu;
    this.cena = cena;
  }

  public DvdNaPredaj() { // v tomto konštruktore sa iba zavolá konštruktor triedy Dvd bez parametrov
  }
  ...
}

Zosumarizujme, čo sa reálne deje pri volaní konštruktora:

  1. zavolá sa rodičovský konštruktor, ktorý zabezpečí vznik objektu, ktorý má schopnosti získané od rodičovskej triedy - ak nie je uvedený, použije sa konštruktor bez parametrov.
  2. vytvoria sa inštančné premenné špecifikované v aktuálnej triede a naplnia sa prednastavenými hodnotami (premenné tried majú null, čísla sú nuly, boolean sú false a char sú '\u0000') a pridajú sa do objektu
  3. spúšťajú sa postupne príkazy v tele konštruktora.
  4. keď sa vykonajú všetky príkazy konštruktora, objekt je vytvorený a vráti sa referencia na tento novovytvorený objekt - obvykle sa táto referencia priradí do premennej, ktorá je rovnakého typu ako trieda, ktorej konštruktor sa vykonával.