Prßce s C++ Builderem vyu╛φvß my╣lenku, ╛e objekt obsahuje
data i k≤d a ╛e s objektem m∙╛eme manipulovat jak b∞hem nßvrhu, tak i p°i
b∞hu aplikace. V tomto smyslu vnφmß komponenty jejich u╛ivatel. P°i vytvß°enφ
nov²ch komponent, pracujeme s objekty zp∙sobem, kter² koncov² u╛ivatel
nikdy nepot°ebuje. P°ed zahßjenφm tvorby komponent, je nutno se dob°e seznßmit
s principy objektov∞ orientovanΘho programovßnφ popsan²mi dßle.
Zßkladnφ rozdφl mezi u╛ivatelem komponent a tv∙rcem komponent
je ten, ╛e u╛ivatel manipuluje s instancemi t°φd a tv∙rce vytvß°φ novΘ
t°φdy.
T°φda je v podstat∞ typ. Jako programßtor, pracujeme
s typy a instancemi, i kdy╛ tuto terminologii nepou╛φvßme. Nap°. vytvo°φme
prom∞nnou typu int. T°φdy jsou obvykle mnohem slo╛it∞j╣φ ne╛ jednoduchΘ
datovΘ typy, ale pracujφ stejn²m zp∙sobem. P°i°azenφm r∙zn²ch hodnot instancφm
stejnΘho typu m∙╛eme provßd∞t r∙znΘ ·lohy. Nap°. m∙╛eme snadno vytvo°it
formulß° obsahujφcφ dv∞ tlaΦφtka (OK a Cancel). Ka╛dΘ z nich
je instance t°φdy
TButton, ale majφ p°i°azeny r∙znΘ hodnoty do vlastnosti
Caption
a r∙zn∞ zpracovßvajφ udßlosti OnClick.
┌Φelem definovßnφ t°φd komponent je poskytnout zßklad
pro u╛iteΦnΘ instance. Tj. cφlem je vytvo°it objekt, kter² my nebo jinφ
u╛ivatelΘ mohou pou╛φvat v r∙zn²ch aplikacφch, v r∙zn²ch situacφch nebo
alespo≥ v r∙zn²ch Φßstech stejnΘ aplikace.
D°φve ne╛ zaΦneme vytvß°et komponenty, pak se musφme
seznßmit s nßsledujφcφmi body, kterΘ se t²kajφ objektov∞ orientovanΘho
programovßnφ:
Odvozovßnφ novΘ t°φdy
Jsou dva d∙vody k odvozenφ novΘ t°φdy:
V obou p°φpadech, je cφlem vytvo°enφ opakovan∞ pou╛iteln²ch
objekt∙. Pokud navrhujeme komponentu jako opakovateln∞ pou╛itou, pak svoji
prßci budeme vyu╛φvat pozd∞ji. Dßme sv²m t°φdßm pou╛itelnΘ implicitnφ hodnoty,
ale umo╛≥ujeme je takΘ p°izp∙sobovat.
Zm∞na implicitnφch
hodnot t°φdy k zabrßn∞nφ opakovßnφ
Ve v╣ech programovacφch ·lohßch se sna╛φme vyhnout se opakovßnφ.
Jestli╛e pot°ebujeme n∞kolikrßt zapsat stejnΘ °ßdky k≤du, pak je m∙╛eme
umφstit do funkce nebo dokonce vytvo°it knihovnu funkcφ, kterou m∙╛eme
pou╛φvat v mnoha programech. Stejn² d∙vod je i pro komponenty. Jestli╛e
Φasto m∞nφme stejnΘ vlastnosti nebo provßdφme stejnΘ volßnφ metod, je u╛iteΦnΘ
vytvo°it nov² typ komponenty, kter² tyto v∞ci provede implicitn∞.
Nap°. p°edpoklßdejme, ╛e poka╛dΘ p°i vytvß°enφ aplikace,
chceme p°idat formulß° dialogovΘho okna k provedenφ jistΘ funkce. AΦkoliv
nenφ obtφ╛nΘ poka╛dΘ znova vytvo°it dialogovΘ okno, nenφ to ale nutnΘ.
M∙╛eme navrhnout okno pouze jednou, nastavit jeho vlastnosti a v²sledek
instalovat na Paletu komponent jako znovupou╛itelnou komponentu. Toto nejen
redukuje opakovßnφ, ale takΘ provßdφ standardizaci.
P°idßnφ nov²ch mo╛nostφ
ke t°φd∞
Jin²m d∙vodem pro vytvß°enφ novΘho typu komponenty je p°idßnφ
mo╛nostφ, kterΘ zatφm existujφcφ komponenta nemß. Lze to provΘst odvozenφm
od existujφcφho typu komponenty (nap°. vytvo°enφm specializovanΘho typu
seznamu) nebo od abstraktnφho zßkladnφho typu, jako je TComponent
nebo TControl. Novou komponentu v╛dy odvozujeme od typu, kter² obsahuje
nejv∞t╣φ podmno╛inu po╛adovan²ch slu╛eb. T°φd∞ m∙╛eme p°idßvat novΘ vlastnosti,
ale nem∙╛eme je odebφrat, tj. jestli╛e existujφcφ typ komponenty obsahuje
vlastnosti, kterΘ nechceme vlo╛it do svΘ komponenty, musφme komponentu
odvodit od p°edka komponenty.
Nap°. jestli╛e chceme p°idat n∞jakΘ mo╛nosti k seznamu,
m∙╛eme odvodit novou komponentu od TListBox. NicmΘn∞, jestli╛e chceme
p°idat n∞jakΘ novΘ mo╛nosti, ale takΘ odstranit n∞kterΘ existujφcφ mo╛nosti
standardnφho seznamu, musφme odvodit sv∙j nov² seznam od TCustomListBox,
tj. p°edka TListBox. Zve°ejnφme mo╛nosti seznamu, kterΘ chceme pou╛φt
a p°idßme svΘ novΘ mo╛nosti.
Deklarovßnφ novΘ t°φdy
komponenty
Kdy╛ se rozhodneme, ╛e je nutno odvodit nov² typ komponenty,
musφme takΘ urΦit od kterΘho typu komponenty svou komponentu odvodφme.
C++ Builder poskytuje n∞kolik abstraktnφch typ∙ komponent urΦen²ch pro
tv∙rce komponent k odvozovßnφ nov²ch typ∙ komponent. K deklarovßnφ novΘho
typu komponenty, p°idßme deklaraci typu do hlaviΦkovΘho souboru jednotky
komponenty.
Nßsledujφcφ p°φklad je deklarace jednoduchΘ grafickΘ
komponenty:
class PACKAGE TPrikladTvaru : public TGraphicControl
{
public:
virtual __fastcall TPrikladTvaru(TComponent
*Owner);
};
Nezapome≥te vlo╛it makro PACKAGE
(definovanΘ v SysDefs.h), kterΘ umo╛≥uje t°φdßm b²t importovßny
a exportovßny.
K dokonΦenφ deklarace komponenty vlo╛φme do t°φdy
deklarace vlastnostφ, polo╛ek a metod, ale prßzdnß deklarace je takΘ p°φpustnß
a poskytuje poΦßteΦnφ bod pro vytvß°enφ komponenty.
P°edci a potomci
Pro u╛ivatele komponent je komponenta entitou obsahujφcφ
vlastnosti, metody a udßlosti. U╛ivatel nemusφ znßt co z toho komponenta
zd∞dila a od koho to zd∞dila. Toto je ale znaΦn∞ d∙le╛itΘ pro tv∙rce komponenty.
U╛ivatel komponenty si m∙╛e b²t jist, ╛e ka╛dß komponenta mß vlastnosti
Top
a Left, kterΘ urΦujφ, kde bude komponenta zobrazena na formulß°i,
kter² ji vlastnφ. Nemusφ znßt, ╛e v╣echny komponenty d∞dφ tyto vlastnosti
od spoleΦnΘho p°edka TControl. NicmΘn∞, kdy╛ vytvß°φme komponenty,
musφme znßt, kterß t°φda od kterΘ t°φdy d∞dφ p°φslu╣nou Φßst. Musφme takΘ
znßt co na╣e komponenta d∞dφ a m∙╛eme tak vyu╛φt zd∞d∞nΘ slu╛by bez jejich
znovuvytvo°enφ.
Z definice t°φdy vidφme, ╛e kdy╛ odvozujeme t°φdu, odvozujeme
ji od existujφcφ t°φdy. T°φda od kterΘ odvozujeme se naz²vß bezprost°ednφ
p°edek na╣φ novΘ t°φdy. P°edek bezprost°ednφho p°edka je takΘ p°edek novΘ
t°φdy; jsou to v╣echno p°edkovΘ. Novß t°φda je potomek sv²ch p°edk∙.
V╣echny vztahy p°edek-potomek v aplikaci tvo°φ hierarchii
t°φd. Nejd∙le╛it∞j╣φ k zapamatovßnφ v hierarchii t°φd je to, ╛e ka╛dß generace
t°φd obsahuje vφce ne╛ jejφ p°edkovΘ. Tj. t°φda d∞dφ v╣e co obsahuje p°edek
a p°idßvß novß data a metody nebo p°edefinovßvß existujφcφ metody.
Jestli╛e nespecifikujeme p°edka t°φdy, C++ Builder odvozuje
t°φdu od implicitnφho p°edka TObject. T°φda TObject je p°edkem
v╣ech t°φd v Knihovn∞ vizußlnφch komponent.
ObecnΘ pravidlo pro volbu od kterΘ t°φdy odvozujeme je
jednoduchΘ: Pou╛ijeme t°φdu kterß obsahuje co nejvφce z toho co chceme
vlo╛it do novΘ t°φdy, ale neobsahuje nic z toho co novß t°φda nemß mφt.
Ke t°φd∞ m∙╛eme kdykoli p°idßvat, ale nelze od nφ nic odstranit.
╪φzenφ p°φstupu
C++ Builder poskytuje p∞t ·rovnφ p°φstupu k Φßstem t°φd.
╪φzenφ p°φstupu urΦuje, kter² k≤d m∙╛e p°istupovat ke kterΘ Φßsti t°φdy.
Specifikacφ ·rovnφ p°φstupu, definujeme rozhranφ na╣φ komponenty. Pokud
nespecifikujeme jinak, pak polo╛ky, metody a vlastnosti p°idanΘ do na╣φ
t°φdy jsou soukromΘ. Nßsledujφcφ tabulka ukazuje ·rovn∞ p°φstupu v po°adφ
od nejvφce omezujφcφho k nejmΘn∞ omezujφcφmu:
Skrytφ implementaΦnφch detail∙
Soukromß Φßst deklarace t°φdy je neviditelnß z k≤du mimo
t°φdu, pokud funkce nenφ p°φtelem t°φdy. SoukromΘ Φßsti t°φd jsou u╛iteΦnΘ
pro ukrytφ implementaΦnφch detail∙ p°ed u╛ivateli komponent. Jeliko╛ u╛ivatelΘ
t°φd nemohou p°istupovat k soukromΘ Φßsti, m∙╛eme zm∞nit vnit°nφ implementaci
objektu bez vlivu na k≤d u╛ivatele.
Pokud nespecifikujeme ╛ßdnΘ °φzenφ p°φstupu na datovΘ
slo╛ky, metody nebo vlastnosti, pak tato Φßst je soukromß.
Nßsledujφcφ p°φklad sklßdajφcφ se ze dvou Φßstφ ukazuje,
jak deklaracφ datov²ch slo╛ek jako soukrom²ch, zabrßnφme u╛ivateli v p°φstupu
k informacφm. Prvnφ Φßst je jednotka formulß°e sklßdajφcφ se z hlaviΦkovΘho
souboru a CPP souboru, kter² p°i°azuje hodnotu soukromΘ datovΘ slo╛ce v
obsluze udßlosti
OnCreate formulß°e. Proto╛e obsluha udßlosti je
deklarovßna ve t°φd∞ TSecretForm, jednotka je p°elo╛ena bez chyby.
Nßsleduje v²pis hlaviΦkovΘho souboru.
#ifndef HideInfoH
#define HideInfoH
#include <vcl\SysUtils.hpp>
#include <vcl\Controls.hpp>
#include <vcl\Classes.hpp>
#include <vcl\Forms.hpp>
class PACKAGE TSecretForm : public TForm
{
__published:
void __fastcall FormCreate(TObject
*Sender);
private:
int FSecretCode;
// deklarace soukromΘ datovΘ slo╛ky
public:
__fastcall TSecretForm(TComponent*
Owner);
};
extern TSecretForm *SecretForm;
#endif
Toto je odpovφdajφcφ CPP soubor:
#include <vcl.h>
#pragma hdrstop
#include "hideInfo.h"
#pragma package(smart_init);
#pragma resource "*.dfm"
TSecretForm *SecretForm;
__fastcall TSecretForm::TSecretForm(TComponent*
Owner)
: TForm(Owner)
{
}
void __fastcall TSecretForm::FormCreate(TObject
*Sender)
{
FSecretCode = 42; // toto
je p°elo╛eno sprßvn∞
}
Druhß Φßst tohoto p°φkladu je jinß jednotka formulß°e,
kterß se pokou╣φ p°i°adit hodnotu datovΘ slo╛ce FSecretCode ve formulß°i
SecretForm.
Zde je hlaviΦkov² soubor:
#ifndef TestHideH
#define TestHideH
#include <vcl\SysUtils.hpp>
#include <vcl\Controls.hpp>
#include <vcl\Classes.hpp>
#include <vcl\Forms.hpp>
class PACKAGE TTestForm : public TForm
{
__published:
void __fastcall FormCreate(TObject
*Sender);
public:
__fastcall TTestForm(TComponent* Owner);
};
extern TTestForm *TestForm;
endif
Nßsleduje odpovφdajφcφ CPP soubor. Proto╛e obsluha udßlosti
OnCreate
formulß°e se pokou╣φ p°i°adit hodnotu datovΘ slo╛ce soukromΘ pro formulß°
SecrectForm,
p°eklad konΦφ chybovou zprßvou (?TSecretForm::FSecretCode? is not accessible).
#include <vcl.h>
#pragma hdrstop
#include "testHide.h"
#include "hideInfo.h"
#pragma package(smart_init);
#pragma resource "*.dfm"
TTestForm *TestForm;
__fastcall TTestForm::TTestForm(TComponent*
Owner)
: TForm(Owner)
{
}
void __fastcall TTestForm::FormCreate(TObject
*Sender)
{
SecretForm->FSecretCode = 13; //zp∙sobφ
p°i p°ekladu chybu
}
I kdy╛ program vlo╛enφm jednotky HideInfo m∙╛e
pou╛φvat t°φdu
TSecrectForm, nem∙╛e p°istupovat k datovΘ slo╛ce
FSecrectCode
v tΘto t°φd∞.
Definovßnφ rozhranφ v²vojß°e
Chrßn∞nß Φßst deklarace t°φdy je neviditelnß z k≤du mimo
t°φdu, co╛ je stejnΘ jako u soukromΘ Φßsti. Rozdφl u chrßn∞nΘ Φßsti je
ten, ╛e t°φda odvozenß od tohoto typu, m∙╛e p°istupovat k jejφm chrßn∞n²m
Φßstem. Chrßn∞nΘ deklarace m∙╛eme pou╛φt k definovßnφ rozhranφ v²vojß°e.
Tj. u╛ivatel objektu nemß p°φstup k chrßn∞n²m Φßstem, ale v²vojß° (nap°.
tv∙rce komponent) ano. M∙╛eme tedy ud∞lat rozhranφ p°φstupnΘ tak, ╛e tv∙rci
komponent je mohou v odvozen²ch t°φdßch m∞nit a tyto detaily nejsou viditelnΘ
pro koncovΘ u╛ivatele.
Definovßnφ b∞hovΘho rozhranφ
Ve°ejnß Φßst deklarace t°φdy je viditelnß pro jak²koli k≤d,
kter² mß p°φstup ke t°φd∞ jako celku. Tj. ve°ejnΘ Φßsti nemajφ ╛ßdnΘ omezenφ.
Ve°ejnΘ Φßsti t°φdy jsou dostupnΘ za b∞hu programu pro v╣echen k≤d a ve°ejnΘ
Φßsti t°φdy definujφ rozhranφ b∞hu programu. Rozhranφ b∞hu programu je
u╛iteΦnΘ pro prvky, kterΘ nezpracovßvßme v dob∞ nßvrhu, jako jsou vlastnosti,
kterΘ zßvisφ na aktußlnφch informacφch o typech za b∞hu programu nebo kterΘ
jsou urΦeny pouze pro Φtenφ. Metody, kterΘ slou╛φ pro u╛ivatele na╣ich
komponent takΘ deklarujeme jako Φßst rozhranφ b∞hu programu. Vlastnosti
urΦenΘ pouze pro Φtenφ nem∙╛eme pou╛φvat b∞hem nßvrhu a uvßdφme je ve ve°ejnΘ
Φßsti deklarace.
Nßsledujφcφ p°φklad pou╛φvß dv∞ vlastnosti urΦenΘ pouze
pro Φtenφ deklarovanΘ jakΘ Φßst b∞hovΘho rozhranφ komponenty:
class PACKAGE TPrikladKomponenty : public
TComponent
{
private:
// implementaΦnφ detaily
jsou soukromΘ
int FTeplCelsius;
int GetTeplFahrenheit();
public:
...
// vlastnosti jsou ve°ejnΘ
__property int TeplCelsius
= {read=FTeplCelsius};
__property int TeplFahrenheit
= {read=GetTeplFahrenheit};
};
Toto je metoda GetTeplFahrenheit v CPP souboru:
int TPrikladKomponenty::GetTeplFahrenheit()
{
return FTeplCelsius * (9 / 5) + 32;
}
I kdy╛ ve°ejnΘ vlastnosti m∙╛e u╛ivatel m∞nit, nejsou
zobrazeny v Inspektoru objekt∙ a tedy nejsou souΦßstφ rozhranφ pro nßvrh.
Definovßnφ nßvrhovΘho rozhranφ
Zve°ej≥ovanß Φßst deklarace t°φdy je ve°ejnß, kterß takΘ
generuje informace o typech za b∞hu programu. Mimo jinΘ, informace o typech
za b∞hu programu zaji╣╗ujφ, ╛e Inspektor objekt∙ m∙╛e p°istupovat k vlastnostem
a udßlostem. Proto╛e pouze zve°ej≥ovanß Φßst je zobrazovßna v Inspektoru
objekt∙, zve°ej≥ovanß Φßst t°φdy urΦuje rozhranφ t°φdy pro nßvrh. Rozhranφ
pro nßvrh zahrnuje v╣e co u╛ivatel m∙╛e chtφt p°izp∙sobit b∞hem nßvrhu,
ale nesmφ obsahovat vlastnosti, kterΘ zßvisφ na informacφch o prost°edφ
b∞hu programu.
Vlastnosti urΦenΘ pouze pro Φtenφ nemohou b²t souΦßstφ
nßvrhovΘho rozhranφ, proto╛e v²vojß° aplikace nem∙╛e do nich p°i°azovat
hodnoty p°φmo. Vlastnosti urΦenΘ pro Φtenφ tedy musφ b²t ve°ejnΘ.
Nßsleduje p°φklad zve°ej≥ovanΘ vlastnosti. Proto╛e je
zve°ej≥ovanß, je zobrazena v Inspektoru objekt∙ p°i nßvrhu.
class PACKAGE TPrikladKomponenty : public
TComponent
{
private:
int FTeplota;
...
__published:
__property int Teplota
= {read = FTeplota, write = FTeplota};
};
Teplota, vlastnost v tomto p°φklad∞, je dostupnß
p°i nßvrhu a u╛ivatel komponenty ji m∙╛e p°i°adit hodnotu v Inspektoru
objekt∙.
Vy°izovßnφ metod
Vy°φzenφ metod je termφn pou╛it² k popisu, jak na╣e aplikace
urΦuje, kter² k≤d bude proveden p°i volßnφ metody. Kdy╛ zapisujeme k≤d,
kter² volß metodu t°φdy, je to stejnΘ, jako volßnφ jinΘ funkce. NicmΘn∞
t°φdy majφ dva r∙znΘ zp∙soby vy°φzenφ metod. Tyto dva typy vy°φzenφ metod
jsou:
Normßlnφ metody
V╣echny metody jsou normßlnφ (ne virtußlnφ), pokud je specißln∞
nedeklarujeme jako virtußlnφ nebo pokud nep°episujeme virtußlnφ metodu
v zßkladnφ t°φd∞. Normßlnφ metody pracujφ jako volßnφ normßlnφch funkcφ.
P°ekladaΦ urΦφ adresu metody a p°ipojφ metodu b∞hem p°ekladu. Zßkladnφ
v²hodou normßlnφch metod je, ╛e jejich vy°φzenφ je velmi rychlΘ. Proto╛e
p°ekladaΦ m∙╛e urΦit adresu metody, metoda je volßna p°φmo.
Dal╣φ rozdφl u normßlnφ metody je ten, ╛e se nem∞nφ v
odvozen²ch typech. Tj. kdy╛ deklarujeme t°φdu, kterß obsahuje normßlnφ
metodu, potom odvozenφm novΘ t°φdy, potomek t°φdy sdφlφ p°esn∞ stejnou
metodu na stejnΘ adrese. Normßlnφ metody tedy v╛dy provßd∞jφ to samΘ, bez
ohledu na aktußlnφ typ objektu. Normßlnφ metodu nelze p°edefinovat. Deklarovßnφm
metody v typu potomka se stejn²m jmΘnem jako mß normßlnφ metoda ve t°φd∞
p°edka se nahradφ metoda p°edka.
V nßsledujφcφm p°φklad∞, objekt typ∙ Odvozena
m∙╛e volat metodu Normalni, jako svou vlastnφ metodu. Deklaracφ
metody v odvozenΘ t°φd∞ se stejn²m jmΘnem a parametry, jako je Normalni
v t°φd∞ p°edka, nahradφ metodu p°edka. V nßsledujφcφm p°φklad∞, kdy╛ je
volßno o->JinaNormalni(), pak bude vy°φzeno nßhradou JinaNormalni
ve
t°φd∞ Odvozena.
class Zakladni
{
public:
void Normalni();
void JinaNormalni();
virtual void Virtualni();
};
class Odvozena : public Zakladni
{
public:
void JinaNormalni();
// nahrazuje Zakladni::JinaNormalni()
void Virtualni();
// p°episuje Zakladni::Virtualni()
};
void PrvniFunkce()
{
Odvozana *o;
o = new Odvozana;
o->Normalni();
// Volßnφ Normalni() jako by byla Φlenem Odvozana
// StejnΘ jako volßnφ o->Zakladni::Normalni()
o->JinaNormalni();
// Volßnφ p°edefinovanΘ JinaNormalni(), ...
// ... nahrazujφcφ Zakladni::JinaNormalni()
delete o;
}
void DruhaFunkce(Zakladni *z)
{
z->Virtualni();
z->JinaNormalni();
}
Virtußlnφ metody
Volßnφ virtußlnφch metod je stejnΘ jako volßnφ jin²ch metod,
ale mechanismus jejich vy°φzenφ je slo╛it∞j╣φ. Virtußlnφ metody umo╛≥ujφ
p°edefinovßnφ ve t°φdßch potomk∙, ale stßle metodu volßme stejn²m zp∙sobem.
Adresa volanΘ metody nenφ urΦena p°i p°ekladu, ale je hledßna a╛ p°i b∞hu
aplikace.
V p°edchozφm p°φklad∞, pokud volßme DruhaFunkce
s ukazatelem na objekt Odvozana, pak je volßna funkce Odvozana::Virtualni().
Virtußlnφ mechanismus dynamicky zji╣╗uje typ t°φdy objektu p°edanΘho za
b∞hu a vy°izuje p°φslu╣nou metodu. Ale volßnφ normalnφ funkce z->JinaNormalni()
bude v╛dy volßnφ Zakladni::JinaNormalni(), proto╛e adresa JinaNormalni
je
urΦena ji╛ p°i p°ekladu.
K deklaraci novΘ virtußlnφ metody, p°idßme klφΦovΘ slovo
virtual
p°ed deklaraci metody. KlφΦovΘ slovo virtual v deklaraci metody
vytvß°φ polo╛ku v tabulce virtußlnφch metod (VTM) t°φdy. VTM obsahuje adresy
v╣ech virtußlnφch metod ve t°φd∞. Tabulka je urΦena za b∞hu k urΦenφ, ╛e
z->Virtualni
bude volat Odvozena::Virtualni a ne Zakladni::Vitrualni.
Kdy╛ odvozujeme novou t°φdu od existujφcφ t°φdy, novß
t°φda zφskß svou vlastnφ VTM, kterß obsahuje v╣echny polo╛ky z VTM svΘho
p°edka a polo╛ky dal╣φch virtußlnφch metod deklarovan²ch v novΘ t°φd∞.
Potomek t°φdy m∙╛e p°edefinovat n∞kterΘ ze zd∞d∞n²ch virtußlnφch metod.
P°edefinovßnφ metody znamenß jejφ roz╣φ°enφ nebo zm∞nu, namφsto jejφho
nahrazenφ. T°φda potomka m∙╛e op∞tovn∞ deklarovat a implementovat libovolnou
z metod deklarovan²ch ve sv²ch p°edcφch.
P°episovßnφ metod
P°episovßnφ metod znamenß roz╣φ°enφ nebo p°edefinovßnφ metody
p°edka, namφsto jejφho nahrazenφ. K p°epsßnφ metody ve t°φd∞ potomka, op∞tovn∞
deklarujeme metodu v odvozenΘ t°φd∞ a zajistφme ╛e poΦet a typy parametr∙
jsou stejnΘ.
Nßsledujφcφ k≤d ukazuje deklaraci dvou jednoduch²ch komponent.
Prvnφ deklaruje dv∞ metody, ka╛dß je jinΘho typu vy°φzenφ. Druhß komponenta
odvozenß od prvnφ, nahrazuje nevirtußlnφ metodu a p°episuje virtußlnφ metodu.
class PACKAGE TPrvniKomponenta : public TComponent
{
void Presun();
// normßlnφ metoda
virtual void Zablesk(); // virtußlnφ
metoda
}
class PACKAGE TDruhaKomponenta : public TPrvniKomponenta
{
void Presun(); //deklaracφ novΘ
metody skr²vßme TPrvniKomponenta::Presun
void Zablesk(); //p°episujeme virtußlnφ
TPrvniKomponenta::Zablesk v p°edkovi
}
Abstraktnφ Φleny t°φd
Kdy╛ metoda je ve t°φd∞ p°edka deklarovßna jako abstraktnφ,
pak ji musφme op∞tovn∞ deklarovat a implementovat v t°φd∞ potomka a to
d°φve ne╛ novou komponentu m∙╛eme pou╛φt v aplikaci. C++ Builder nem∙╛e
vytvß°et instance t°φd obsahujφcφ abstraktnφ slo╛ky.
T°φdy a ukazatelΘ
Ka╛dß t°φda (a tedy i ka╛dß komponenta) je ve skuteΦnosti
ukazatel na t°φdu. P°ekladaΦ automaticky dereferencuje ukazatel t°φdy za
nßs a my o tom nic nevφme. Toto se ale stßvß d∙le╛itΘ, kdy╛ p°edßvßme t°φdy
jako parametry. P°i p°edßvßnφ t°φdy je vhodn∞j╣φ pou╛φt parametr volan²
hodnotou ne╛ odkazem. T°φdy jsou ve skuteΦnosti ukazateli, kterΘ jsou ji╛
odkazem. P°edßnφm t°φdy odkazem je vlastn∞ p°edßvßn odkaz na odkaz.
![](/file/23413/Chip_2002-07_cd1.bin/chplus/cpp/5/PreviousArrow.gif) ![](/file/23413/Chip_2002-07_cd1.bin/chplus/cpp/5/NextArrow.gif) ![](/file/23413/Chip_2002-07_cd1.bin/chplus/cpp/5/WayUpArrow.gif) |
2. OOP pro tv∙rce komponent
|