Ahoj vsichni,
uz jsem se pri svem seznamovani s Javou stacil dozvedet ze volani
konstruktoru nadrazene tridy (tedy "super(...)") musi byt v novem
konstruktoru hned jako prvni prikaz. Netusite nekdo jaky to ma
duvod?
Ted jsem chtel vytvorit konstruktor ktery by pred zavolanim sveho
super() vykonal validaci parametru, ale tvrde jsem narazil takze
musim pouzit nehezky workaround. Vrta mi hlavou jake tohle omezeni
muze mit duvod...?
:-) Symptomaticky, v tomhle ohledu se jinak podobne jazyky C++, Java,
C# chovaji kazdy trochu jinak, a vsechny nekonzistentne; napriklad
Java dovoli
pred volanim zakladoveho konstruktoru provadet vyrazy, vcetne volani
zdedenych ci nezdedenych metod, ale nedovoli provadet prikazy
normalnim
zpusobem, ktery byste rad videl. (Navic zminene vyrazy musi
predstirat,
ze se podileji na sestavovani seznamu argumentu pro zakladovy
konstruktor - pokud ovsem budete trvat na stupni inteligence,
kterou jste
svemu konstrukturu v puvodnim navrhu prisoudil.)
Proc takove propracovane a povetsinou konzistentni jazyky jako
C++, C#, Java v tehle casti syntaxe jakoby tapou? Asi proto, ze
v intuici za konstruktory je rozpor.
Ideove poslani konstruktoru je prakticke vynuceni invariantu platnych
pres vsechny objekty urcite tridy. Nejlepe by melo byt mozne sdilet
logiku (metody) pouzivanou pro vytvareni objektu s logikou
pouzivanou za
normalniho provozu. Jenze behem vytvareni objektu ty invarianty jeste
neplati, a kdyz se na ne nebudu spolehat v prislusne provozni
logice, tak
zase jsou temer k nicemu. Dusledek: konstruktory by se "mely"
vyhybat volani
cehokoli vnejsiho, cehokoli chytreho. U nefinalnich trid je casto
nebezpecne
dokonce i volani na samem konci konstruktoru(*).
Jinak receno, logika konstrukce by vzdy mela byt radove jednodussi,
nez logika
provozu. Pokud pripustite sofistikovane konstrukce jako
class X {
X(int param) {
if (param > 3) {
super(param, true);
}
...
}
...
}
(a sesmolite jakasi pravidla, asi aby se volal vzdy presne jeden
zakladovy
konstruktor), je velmi pravdepodobne, ze se tato konstrukce bude
vyskytovat prevazne v nevhodnych navrzich. Na druhou stranu pokud
nedovolite vubec zadne zasahovani do retezeni konstruktoru, dosahnete
proste jeste vyssiho stupne konstruktoroveho balastu (duplikace kodu),
nez je v Jave ci C#, tak jak jsou, bezne.
Takze Java zde dava urcity arbitrarni kompromis. Vetsinou se
nevyplati ho
workaroundovat; lepsi byva v momente, kdy citite tyto syntakticke
priznaky
prilis chytreho retezu konstruktoru, proste vyndat cast konstrukce
mimo
konstruktor (u Vas neco jako public virtual void validate()
throws ...).
Dalsi moznost je prejit na jednoduche neviditelne (soukrome)
konstruktory
a verejnou statickou "tovarni" metodu.
I kdyz treba v tehle zalezitosti muzete mit neco jako "pravdu", tak
v boji
s jazykem vitezstvi byvaji prechodna. Nicmene hodne stesti.