Abbiamo visto che Delphi permette di specificare anche altri parametri nella
dichiarazione delle proprietà di una classe e tra questi ci sono gli specificatori di
indice che permettono la condivisione dello stesso metodo a più proprietà. L'indice
serve, appunto, a distinguere per quale propietà il metodo sta lavorando. Infatti
l'indice specificato nella dichiarazione della proprietà viene automaticamente passato al
metodo che decidarà le istruzioni da eseguire in base al valore dell'indice. Per definire
uno specificatore di indice occorre indicare nella dichiarazione della proprietà, dopo il
tipo della proprietà stessa, la direttiva index seguita da una costante
integer. Anche per gli specificatori di indice per gli specificatori di accesso possono
essere definiti solamente dei metodi che per lo specificatore di accesso read devono
contenere come ultimo parametro passato alla funzione un parametro aggiuntivo di tipo
integer e per lo specificatore write deve essere una procedura che tra i
parametri passatigili contenga un ulteriore parametro, sempre di tipo integer, posizionato
però dal secondo all'ultimo posto nella lista dei parametri e comunque prima del
parametro contenente il valore da assegnare alla proprietà.
Gli specificatori di memorizzazione
Gli specificatori di memorizzazione servono ad indicare a Delphi come gestire il
salvataggio delle informazioni RTTI , ovvero se salvare o meno i valori delle proprietà
published nei file form (.DFM). Questi sono: stored, default,
nodefault e sono specificatori facoltativi.
La direttiva stored indica a Delphi se il valore di quella proprietà
deve essere salvato o no nel file form. Questa deve essere seguita dal valore boolean true
o False. Se non viene specificato alcun specificatore stored
Delphi salva automaticamente il valore della proprietà.
La direttiva default indica a Delphi quale è il valore di di default
per quella proprietà se nel file form non è specificato alcun valore. Abbiamo visto
l'uso di questa direttiva nelle proprietà array, ma in questo caso si comporat
diversamente. Infatti in questo caso va seguita da una costante dello stesso tipo della
proprietà; lo specificatore di default è valido solamente per i tipi ordinal e set
sempre che i loro valori massimi e minimi siano compresi tra 0-31. Se nella dichiarazione
della proprietà non viene indicata ne la direttiva default o nodefault,
Delphi considera come se fosse stata utilizzata la direttiva nodefault.
Operatori di classe
Delphi mette a disposizione degli opreratori speciali per operare sulle classi. Questi
operatri utilizzano dei metodi definiti nel tipo TObject e che vengono ereditati
da ogni classe. Questi operatori sono is e as e fanno
uso dei metodi derivati da TObject, ClassType, ParentClass, InheritsFrom.
L'operatore is esegue il controllo dinamico del tipo di un oggetto in
fase di esecuzione per verificare la classe attuale dell'oggetto stesso. L'utilizzo
dell'operatore is è il seguente
Oggetto is Classe
Questa espressione restituisce true se l'istanza di Oggetto è
un'istanza della classe Classe o da uno dei suoi discendenti. Se Oggetto
vale nil il risultato della valutazione è False. Il tipo di Oggetto
e Classe devono essere correlati fra loro ovvero essere uno l'antenato
dell'altro, altrimenti in fase di compilazione viene generato un errore.
L'operatore as serve ad eseguire conversioni di tipo ovvero dato
un'istanza di Oggetto ed un classe Classe l'espressione
Oggetto as Classe
restituisce un riferimento all'oggetto Oggetto ma con il tipo indicato
da Classe. Come per l'operatore is, l'istanza Oggetto
e la classe Classe devono essere correlati ovvero essere uno l'antenato
dell'altro altrimenti si avrà la generazione di un errore di compilazione. In fase di
esecuzione Oggetto deve essere un'istanza della classe Classe o nil
pena il sollevamento di un'eccezione. Un esempio dell'utilizzo dell'operatore as
(Sender as TLabel).Caption := 'Elaborazione in corso...';
Le regole di precedenza dell'operatore as richiedono a volte che
l'intera espressione contenente l'operatore venga racchiusa tra parentesi. Nessun problema
comunque se si utilizza normalmente questa pratica per evitare errori e perdita di tempo
nel debug del codice.