2. OOP pro tv∙rce komponent

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:
 
┌rove≥ V²znam Pou╛φvß se pro
private P°φstupnΘ pouze v k≤du v jednotce, kde t°φda je definovßna. Skrytφ implementaΦnφch detail∙ 
protected P°φstupnΘ v k≤du v jednotkßch, ve kter²ch t°φda a jejφ potomci jsou definovßny. Definovßnφ rozhranφ tv∙rce komponenty 
public P°φstupnΘ ve v╣em k≤du. Definovßnφ rozhranφ pro b∞h programu 
__published P°φstupnΘ ve v╣em k≤du a z Inspektora objekt∙. Definovßnφ rozhranφ pro nßvrh 
__automated P°φstupnΘ ve v╣em k≤du. Je generovßna informace o typu Automatizace. Pouze pro automatizaci OLE

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.
 
2. OOP pro tv∙rce komponent