INHERITS

Da Gambas-it.org - Wikipedia.

INHERITS <ParentClass>

Questa istruzione nella costruzioni di oggetti (o classi), basati su una specifica classe padre (Parent), e da cui prende tutte le caratteristiche che la identifica: proprietà e metodi. In realtà, dalla classe padre, è possibile derivare solo le proprietà e i metodi dichiarati PUBLIC, mentre per quanto riguarda il resto, PRIVATE, resta di uso strettemente della classe in cui sono dichiarati. In questa logica sono anche comprese le costanti CONST (PUBLIC CONST) e le proprietà e i metodi STATIC (STATIC PUBLIC).

Anche nelle librerie Gambas sono presenti oggetti, le cui caratteristiche derivano dalla inerenza da oggetti superiori; un esempio potrebbe essere la classe Button, che discende dalla classe Control. Un'altro esempio è la stessa classe Form, che seppur dichiarata non creabile dinamicamente, discende dalla classe Window, che a sua volta discende dalla classe Container, che a sua volta discende dalla classe Control. Come si può notare, la discendenza, o inerenza, tra gli oggetti può essere molto complessa, ma ad ogni passaggio, ogni fliglio apporta nuove caratteristiche alla classe, rendendola sempre più specializzata. Non sono qui ad aprire un discorso sul tema della classi, perchè sarebbe lungo e fuori luogo, e inoltre esiste una montagna si documentazione in giro, che il mio risulterebbe un contributo piuttosto striminzito.

Ma torniamo a noi...

L'istruzione INHERITS è molto semplice, ma deve essere necessariamente la prima istruzione della classe (ad esclusione delle note...), e l'oggetto ParentClass deve essere già presente nel progetto, o nelle librerie di Gambas. Diversamente dalle versioni precedenti di Gambas, ora è possibile derivare un numero imprecisato di sottoclassi, ma non è possibile creare oggetti dipendenti da più di una classe parent contemporaneamente. Tranne che per gli oggetti Form, e gli oggetti STATIC in generale, inclusi nelle librerie di base, è possibile creare nuove classi derivandoli da quelli già presenti in Gambas. E' sottinteso che qualsiasi altro nostro oggetto, può essere subclassato senza alcun problema.

Una volta che una classe è stata dichiarata sottoclasse di un'altra, ne prende le caratteristiche; ogni modifica alle sue proprietà viene riflessa anche alle proprietà della classe superiore, questo include anche la possibilità di sovrascrivere un determinato metodo in modo che si comporti in modo diverso rispetto alla classe superiore.

Per fare un esempio, vogliamo creare un oggetto di tipo Button, a cui però vogliamo modificare o aggiungere nuove caratteristiche, oppure addirittura modificarne il comportamento, è sufficiente creare una nuova classe, e dichiararla INHERITS a Button:


 INHERITS Button

Una volta definita la sua discendenza dalla classe superiore Button, non è necessario richiarare e ridefinire le caratteristiche che la nuova classe si ingloba con questa unione; questo a meno che non si voglia condizionare alcune delle funzionalità della classe superiore, per meglio adattarle alla nuova classe. Ma, a parte questo, lo scopo reale nell'avere costruito questa nuova classe, sarebbe quello di specializzarne la funzione, rispetto alla classe padre. Di idee ce ne potrebbero diverse, ma possiamo cercare di capire con un semplice esempio.

Ammettiamo di voler creare questa nuova classe Button, con lo scopo di renderla standard e utilizzabile per un determinato scopo all'interno della nostra applicazione; questo fa sì che una volta definite le caratteristiche particolari di questo nuovo pulsante, non ci si debba più preoccupare del suo funzionamento all'interno delle procedure in cui lo inseriremo. Ammettiamo il molto semplice caso di un pulsante utilizzabile per l'uscita da una Form, ovvero, cliccando su questo pulsante, l'evento di Click ci chiude la form:


Creiamo il pulsante e le proprietà e i metodi che ci servono:

 INHERITS Button
 ...
 ...
 PUBLIC SUB _new()
   ...
   Object.Attach(ME, ME, "Event")
   ...
 END
 PUBLIC SUB Event_Click()
   ME.Parent.Close()
 END

Come si può vedere, nell'esempio ho derivato la classe (chiamiamola 'CloseButton') dalla classe Button, in modo da prenderne tutte le caratteristiche; tramite il metodo nascosto "_new()" (Metodi nascosti), ho fatto in modo da definire un'etichetta precisa "Event" per tutti gli eventi legati al pulsante, e che questi eventi sono dichiarati all'interno della stessa classe: Object.Attach(<oggetto pulsante>, <classe gestore eventi>, <nome eventi>). Poi ho dichiarato il metodo Event_Click(), per la risposta all'evento di click sul pulsante; all'interno dell'evento è il codice per chiusura della form. Il puntamento alla form viene fatto dalla proprietà "Parent" derivata dalla classe padre Button, a cui è stato passato il riferimento all'oggetto contenitore (la Form), infatti, la creazione del pulsante:


 ...
 DIM MyButton AS NEW CloseButton(hForm)
 ...

In questo esempio, mi pare ovvio che la parent diretta del nostro pulsante sia un Form, ma potrebbe anche essere un Panel, o un'altro oggetto contenitore; in questo caso è sufficiente passare l'esatto riferimento alla form per la sua chiusura.

A parte il puerile esempio che ho descritto, la particolare funzione dell'istruzione INHERITS è di indubbia utilità, e apre un vasto mondo di possibilità, slegando enormemente lo sviluppo di applicazioni dalle sole librerie di base di Gambas.