Finora si sono sempre create due sezioni distinte:
quella dei dati e quella del codice;
un oggetto si può immaginare come l'evoluzione di un record ma che al contrario di questo
contiene procedure e funzioni. Ad esempio l'oggetto TTelevisione disporrà delle proprietà
Spina, Antenna, Interrutore, Volume, Frequenza ed dei metodi
Accendi, Spegni, Sintonizza, AlzaVolume e AbbassaVolume. A livello di codice l'oggetto
TTelevisione apparirà definito come segue:
Type TTelevisione = class
Per utilizzare l'oggetto TV basterà creare una
variabile che faccia riferimento all'oggetto TTelevisione stesso, ad
esempio il codice
Spina: (Inserita, Disinserita);
Antenna: (Portatile, Normale, Satellitare);
Interruttore: (ON, OFF);
Volume: Byte;
Frequenza: Byte;
procedure Accendi;
procedure Spegni;
procedure Sintonizza(Canale: Byte);
procedure AlzaVolume;
procedure AbbassaVolume;
constructor Create;
end;
Procedure TTelevisione.Accendi;
Begin
If Spina = Disinserita Then
Spina:= Inserita;
If Interruttore = OFF Then
Interruttore:= ON;
End;
Procedure TTelevisione.Spegni;
Begin
If Spina = Inserita Then
Spina:= Disinserita;
If Interrutore = ON Then
Interruttore:= OFF;
End;
Procedure TTelevisione.Sintonizza(Canale: Byte);
Begin
If Frequenza <> Canale Then
Frequenza:= Canale;
End;
Procedure TTelevisione.AlzaVolume;
Begin
Volume:= Volume + 10;
End;
Procedure TTelevisione.AbbassaVolume;
Begin
Volume:= Volume - 10;
End;
Constructor TTelevisione.Create;
Begin
Frequenza:= 1;
Spina:= Inserita;
Interruttore:= ON;
Volume:= 30;
Antennza:= Satellitare;
End;
Var TV: TTelevisione;
rende possibile
utilizzare l'oggetto TTelevisione tramite la variabile TV.
Il Primo passo sarà quindi di inizializzare l'oggetto TV tramite l'istruzione TV:=
TTelevisione.Create;
cioè assegna alla variabile TV l'oggetto
TTelevisione inizializzato dal constructor Create; Vi chiederete ora cosa sia un
constructor, o perchè si debba seguire questa prassi, le risposte non sono semplici e
dovrete per ora accontentarvi di imparare questo come un fatto scontato perchè tutti gli
oggetti sono strutturati in questo modo (è buona norma far
iniziare il nome di un oggetto con la T).
Come consuetudine di questo corso propongo un piccolo sorgente esplicativo.
Program WinForm;
Uses
Forms;
Var
frmHello: TForm;
Begin
frmHello:= TForm.Create(nil);
frmHello.Caption:= 'Hello Object programming';
frmHello.Position:= poScreenCenter;
frmHello.ShowModal;
frmHello.free;
End.
Il programma crea una variabile frmHello derivata dall'oggetto TForm e
quindi ne eredita tutti i metodi, le proprietà nonchè le caratterestiche intrinsiche
non accessibili direttamente dal programmatore.
L'istruzione frmHello:= TForm.Create(nil);
assegna alla
variabile l'oggetto TForm inizializzato; probabilmente nel constructor create vengono
settate a nulle le variabili interne, viene settata un'icona di default e preparate alcune
proprietà che determinano l'aspetto della finestra (forma, colore, etc.).
Nell'istruzione seguente la proprietà caption viene cambiata in modo di visualizzare uno
specifico titolo, la finestra viene quindi centrata (frmHello.Position:=
poScreenCenter;
) e visualizzata (frmHello.ShowModal;
).
Infine è buona norma richiamare il motodo free di ogni
oggetto per liberare tutta la memoria allocata dallo stesso tramite il
constructor create.
![]() |
|
E' ora spiegato perchè quando si crea una nuova Form viene creato automaticamente il
codice
Type TForm1 = class(TForm);
...
...
...
Var
Form1: TForm1;
Cioè viene creato un nuovo oggetto TForm1 che erdita automaticamente tutte le
caratteristiche di TForm (detto oggetto Ancestor o Padre). La riga Var
Form1: TForm1
rende accessibile l'oggetto TForm1 tramite la variabile
Form1.
Come già accennato un oggetto può essere un "erede" di un altro. L'OOP
permette però all'oggetto discentdente di modificare il comportamento standard
dell'oggetto ancestor. Ad esempio supponiamo di voler creare l'oggetto TAdvancedTelevision
discendente dell'oggetto TTelevision che dispone di tutte le caratteristiche della classe
ancestor ma anche delle proprietà colore e forma. L'oggetto TAdvancedTelevision sarà
così definito
Type TAdvancedTelevision = class(TTelevision)
Colore: (Rosso, Giallo, Verde, Blu);
Forma: (Cubo, Parallelepipedo, Standard);
constructor Create; ovverride;
constructor TAdvancedTelevision.Create;
begin
inherited Create;
Colore:= Rosso;
Forma:= Standard
end;
Si noti che dopo la definizione del prototipo del constructor Create è stata inserita la
direttiva ovverride per comunicare al compilatore che si sa sovrascrivendo il construtor
TTelevision, tuttavia la prima istruzione del construtor è inherited Create;
che serve per ereditare il construtor dell'ancestor. Se non si provvedesse ad ereditare il
vecchio constructor l'oggetto TAdvancedTelevision non avrebbe le proprietà Volume,
Antenna, etc. inizializzate.
TIP | ![]() |
Quando si sovrascrive un constructor la prima istruzione deve essere
necessariamente inherited Create; , viceversa nella sovrascrittura di un
destructor l'istruzione inherited Destructor; deve essere l'ultima, questo
per evitare perdite di memoria o scorrette inizializzazioni delle variabili. |
Si noti che per ereditare un oggetto si utilizza l'istruzione Type Discendente =
class(Antenato)
.
TIP | ![]() |
In effetti anche l'oggetto TTelevisione era un discendente della classe
TObject, l'istruzione Type Discendente = class corrisponde alla definizione Type
Discendente = class(TObject) .L'oggetto TObject mette a disposizione un constructor
Create, un destructor Destroy e infine un metodo free. |
Un'ultima osservazione sull'ereditarietà è che un oggetto discendente può essere
posto all'assegnazione (:=) con l'antenato ma non viceversa. A livello di codice questo
significa che:
Discendente:=
Antenato;
è sintatticamente corretto, ma viceversa
Antenato:=
Discendente;
provoca un errore di compilazione. questo perchè l'oggetto ancestor non dispone di tutti
i dati del discedente.
TIP | ![]() |
Alcuni oggetti, specialmente quelli grafici, possono tranquillamenti
lavorare con l'operatore di assegnazione, tutttavia è altamente scorretto (per motivi che
non sto qui a spiegarvi). al posto dell'istruzione Bitmap1:= Bitmap2; usare
quindi Bitmap1.Assign(Bitmap2) . |
La programmazione ad oggetti potrebbe sembrare in prima fase tanto complessa ma inutile, nella realtà è più semplice ed efficacie di quanto possa sembrare da questo capitolo che purtroppo è puramente teorico. Nella sezione "creazione di oggetti VCL" si riprenderà quanto appreso qui per metterlo in pratica con esempi in Delphi.
Corso interamente creato da VB.