Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailemVyřešeno OOP (Delphi) - Ako volať v potomkovi konštruktor z premennej predka (override)?

V mojom programe využívam virtuálne abstraktné metódy, aby som umožnil metódam potomka volať vlastné metódy z objektovej premennej predka pri uložení premennej potomka. Príklad:

PremennaPredka := TPotomok.Create
PremennaPredka.Metoda

Lenže mám tu taký objekt, ktorý uchováva v sebe ako vlastnosť jeden objekt, z ktorého sú odvodené ďalšie. Keďže všetky dôležité metódy v uchovanom objekte sú deklarované ako virtual abstract, tak sa volajú správne metódy potomka*. Ale čo ak chcem zavolať konštruktora tohto objektu? Zavolá sa konštruktor predka alebo potomka? Ešte som nevidel deklaráciu konštruktora so slovom override alebo virtual, príp. dynamic. Zatiaľ je konštruktor prázdny a teda je štandardný, ale čo ak ho vytvorím?

Edit: Opravené slovo predka na správne potomka.

Předmět Autor Datum
V prepsanem Constructor poromka zavolas: inherited Create() { a pak napises vlastni kod}
Jan Fiala 26.12.2006 13:04
Jan Fiala
Lenže ja to mám definované takto: NovyObjekt = objekt Predok: TPredok; ostatne_vlastnosti_a_metody;…
msx. 26.12.2006 13:27
msx.
Pozoruju, že v tom máš trošku hokej. Můžeš myslet dvě možnosti: 1. Děláš nějaký seznam uzlů, kde má…
Rce 27.12.2006 00:21
Rce
Áno, takže som na to išiel dobre, len som nevedel, ako odovzdať typ a nie hodnotu. Stačilo mi odovzd…
msx. 27.12.2006 12:59
msx.
Ještě drobnost v názvosloví. Nepředáváš typ ale třídu. Typ je třeba record (staré objekty - dodnes v…
Rce 27.12.2006 23:32
Rce
construktor - to je v akom jazyku? :-p
los 27.12.2006 23:41
los
:))8-)
Rce 28.12.2006 00:04
Rce
Áno, všetko mám definované ako class(). Ja som si dokonca myslel, že object() v Delphi neexistuje. N…
msx. 28.12.2006 02:14
msx.
Třeba v TObject je hned několik metod, které lze volat odkazem na třídu i na objekt (Třída = definic… poslední
Rce 28.12.2006 22:52
Rce
Prohledni si componenty v delphi zdrojove kody tam najdes jak na to taky cesta priklad : jednotka:\B…
virus 26.12.2006 19:13
virus
No skúsim to. Našťastie to neponáhľa, takže keď na to dôjde, tak to budem dovtedy hádam už vedieť.
msx. 26.12.2006 19:29
msx.

Lenže ja to mám definované takto:

NovyObjekt = objekt
  Predok: TPredok;
  ostatne_vlastnosti_a_metody;
  constructor Create(Nieco: TPredok);
end;

No a potom zavolám:

NovyObjekt.Create(PotomokPredka);

No a Create() vyzerá takto:

constructor NovyObjekt.Create(Nieco: TPredok);
begin
  Predok := Nieco;
end;

Ja to chcem tak, že Nieco vytvorím v NovyObjekt.Create() a aby sa zavolal konštruktor Potomka. Aha, takže práve vidím, že v tom problém nebude, pokiaľ neodovzdám ako parameter inštanciu potomka (keďže ešte nie je vytvorený), ale len čisto typ potomka. No a myslím, že tu som na hranicí možností Delphi. Odovzdávanie typu miesto hodnoty som ešte myslím nevidel. Ako na to?

Edit: IMHO, tiež by to vyriešilo, keby som ako parameter odovzdal odkaz na konštruktora objektu PotomokPredka. Ale konštruktor ako paramaeter metódy je asi nemožný, je tak?

Pozoruju, že v tom máš trošku hokej. Můžeš myslet dvě možnosti: 1. Děláš nějaký seznam uzlů, kde má každý uzel svého potomka a předka. Nebo se ti jedná o takovýto případ:

TPredek =  class (object)
    Nějaké-deklarace
    Constructor Create (....);
end;
TPotomek = class (TPredek)
    Nějaké-deklarace
    Constructor Create (....);
end;

Pak při vytvoření instance Potomek := TPotomek.Create (x); oba objekty (TPredek a TPotomek) jedno jsou. Self v obou třídách ukazuje na tentýž objekt a není třeba rozlišovat nijak jestli je někde TPotomkem nebo TPredkem. Je to rozlišeno jen umístěním kódu - proto jsou virtuální metody. Aby se dalo z TPredek volat metoda TPotomka, i když jí defakto kompilátor v době kompilace nezná. Není třeba se tím nijak vzrušovat ani to extra zpracovávat, obvykle to kompilátor udělá vždycky dobře - protože objekt je identický a obsahuje všechny metody a vlastnosti (záleží jen, které jsou odkad volatelné - na nestandartní volání je možno v pohodě použít přetypování).

Jestli ti jde skutečně o vytvoření nového potomka takto:

constructor NovyObjekt.Create(Nieco: TPredok);
begin
  Predok := Nieco;
end;

kde Nieco typu TPredok nemá s NovObject vůbec nic společného, nelze to takto udělat. Musíš předávat odkaz na třídu, asi takhle:

TPredok = class (object)
...
end;

TPredokClass = class of TPredok;

NovyObjekt = objekt
  Predok: TPredok;
  ostatne_vlastnosti_a_metody;
  constructor Create(Nieco: TPredokClass);
end;

---
---
constructor NovyObjekt.Create(Nieco: TPredokClass);
begin
  Predok := Nieco.Create (...);
end;

Áno, takže som na to išiel dobre, len som nevedel, ako odovzdať typ a nie hodnotu. Stačilo mi odovzdať typ, ale ten sa bežným spôsobom odovzdať nedá. Takže class of slúži na vytvorenie "potomka typu" a object slúži na vytvorenie potomka objektu. Ďakujem, presne toto som potreboval.

Ještě drobnost v názvosloví. Nepředáváš typ ale třídu. Typ je třeba record (staré objekty - dodnes v Delphi fungující - jsou spíš jako záznam). Když definujeme něco, založené na TObject (a výš), je to třída (class). Třída má oproti typům navíc vlastnosti (properties) a metody. Za určitých okolností lze volat metody třídy bez instance objektu (tyto metody jsou uvedeny klíčovým slovem CLASS - například class procedure ...; class function ...;). Velice známým zástupcem metod třídý je construktor.

Třeba v TObject je hned několik metod, které lze volat odkazem na třídu i na objekt (Třída = definice, typ; Objekt = instance třídy, objekt vytvořený z třídy třebas TClass.Create (...)):

class function ClassName: ShortString;
class function ClassNameIs(const Name: string): Boolean;
class function ClassParent: TClass;
class function ClassInfo: Pointer;
class function InstanceSize: Longint;
class function InheritsFrom(AClass: TClass): Boolean;
class function MethodAddress(const Name: ShortString): Pointer;
class function MethodName(Address: Pointer): ShortString;

Vidíme, že všechny tyto metody mají opodstatnění, aby se volaly přes odkaz na třídu. Například ClassParent vraci rodiče třídy, InstanceSize vrací potřebnou velikost paměti pro vytvoření instance třídy. Atd... :-);-)

Zpět do poradny Odpovědět na původní otázku Nahoru