Newsgroup: it.comp.lang.visual-basic
Titolo: [?] Ereditarieta tra classi, possibile ?

Salve a tutti, sto scrivendo una classe che deve permettere di gestire
una tabella di una database permettendi l'inserimento, variazione,
eliminazione dei record.
O concepito la classe in modo che la classe possa gestire tabelle
diverse da istanza a istanza, passane il nome al momento
dell'inizializzazione, faccio un'esempio:
dim clienti as clsData, fornitori as clsData
set clienti = new clsData
set fornitori = new clsData
call clienti.inizializza( cntDB, "clienti" )		
' *** cntDB = connessione al database che contiene la tabella
' *** "clienti" = nome della tabella da gestire
call fornitori.inizializza( cntDB, "fornitori" )
in questo modo avro' le due istanze di clsData, una che gestisce la
tabella "clienti" e l'altra la tabella "fornitori"
per assegnarei i valori ai campi del record avro' il metodo setfield,
esempio:
call clienti.setfield( "nomecampo", valorecampo )
il valore che viene passato al campo viene conservato nella classe in
un'array di tipo variant e al momento in cui vado scrivere il record
dovrei prendere i valori da questo array.
la domanda e' questa:
volendo implementare nalla classe dei metodi
clsData.search( chiave_di_ricerca )
clsData.insert( )
clsData.update( )
che per forza di cose questi metodi devono essere personalizzati da
tabella a tabella.
Come posso fare questo ???
Avrei pensato di creare una classe base senza metodi che poi dovranno
essere diversi da istanza a istanza, creare una seconda classe facendo
in modo che erediti la classe base. Esempio
clsData
metodo inizializza( cnt, tab ) 
clsDataClienti eredita clsData
metodo search( key )
metodo insert( ) 
metodo update( ) 
Il problema e' che a quanto ho capito in visualbasic non esiste
ereditarieta' tra classi.
Esistono le interfacce pero' su queste non si puo' inserire codice in
modo da poterlo riutilizzare sulle classe figlie.
Secondo voi e' possibile fare una cosa del genere ????
Ciao

 dell'inizializzazione, faccio un'esempio:
<Ecc. Ecc.>
La questione "ereditarietà" è un problema non tanto di VB quanto di COM.
Si può discutere qui di ereditarietà e di polimorfismo e quel che vuoi, ma
il problema rimane: sarebbe carino ma non puoi farlo. Forse capisci perchè
si passa a .NET che invece è un ambiente di sviluppo ad oggetti (invece che
a COMponenti com'è adesso).
E non mi dilungo sulle lodi e sui problemi di COM, che amo e odio allo
stesso tempo, tralasciando il sangue sudato dietro DCOM...
Qui mi pare tu stia cercando di realizzare una classe che gestisca DATI
diversi di tabelle diverse, e secondo me hai una grande mano d'aiuto dalla
libreria ADODB.
Non so se hai mai notato che la "forma" degli oggetti ADO: è molto carina
perchè nessun oggetto necessita di un altro oggetto della stessa famiglia
per la sua esistenza.
So che questo è un concetto per molti piuttosto oscuro e sicuramente
difficile da discutere qui, ti dirò soltanto che un Recordset ADO esiste a
prescindere dalla sua connessione al DB, pertanto puoi usare questo oggetto
nella tua classe: quando "inizializzi" passi anche un oggetto di tipo
connessione già aperto (oltre al nome tabella o alla query) lui si collega e
scarica i dati (se serve) quindi butta la connessione (set
ADORS.ActiveConnection=Nothing).
Guardacaso il Recordset ha una collection di campi (ADORS.Fields) che usi
già come sistema per accedere ai campi della tua classe, e guardacaso il
recordset si comporta di conseguenza relativamente a cosa ci hai messo
dentro: la sua update, la sua delete, ecc. sono collegate alla tabella dei
dati o al risultato di una select che rappresenta.
Un Recordset ADO, essendo un oggetto standard, puo' essere referenziarlo da
qualsiasi parte del tuo sorgente e puoi usarlo come parametro di una
funzione, come valore restituito da una funzione o come proprietà della tua
classe.
Sono arrivato sin qui e mi sono reso conto che, in effetti, parlare di
questa cosa in un newsgroup è abbastanza difficile (almeno per me). Ma spero
di averti dato lo start per arrivare all'idea giusta.
Ciao,
Dads.


[cut]
Splendida sintesi dei punti di forza più significativi di Ado.
ciao
ugo

 Secondo voi e' possibile fare una cosa del genere ????
Potresti farlo con i solito sistema per delega... in sostanza puoi definire
l'interfaccia includendo nello stesso tempo il codice comune nei vari metodi
(non e' che "non si puo'", piu' che altro "non si dovrebbe" ma funziona
essendo a tutti gli effetti una normale classe);
Ora nelle classi figlie fai qualcosa del genere
Implements IMain
'istanza privata della classe principale; serve per poter
'richiamare i metodi base nelle implementazioni dei nostri
Private objMain As IMain
Private Sub Class_Initialize()
'dobbiamo sempre avere un'istanza valida
Set objMain = New IMain
End Sub
a questo punto hai a disposizione un riferimento all'interfaccia che puoi
usare per richiamare i metodi comuni integrandoli eventualmente con il
codice specifico per le diverse classi figlie.
Questo sistema (al momento, ahime', l'unico) dovrebbe essere anche descritto
su MSDN in "Implementazione di interfacce e polimorfismo" o giu' di li'...
Ciao
--
Luca Dormio - 
luca....@tin.it
________________________________
"Marty, non stai ragionando in maniera quadridimensionale"
Dr. Emmett L. Brown


Ti ringrazio per la tua lunge ed esauriente spiegazione, sei stato
chiarissimo.
Ciao,
David.


All'MSDN gli ho dato un'occhiate e mi sembra che spiegi solo come
funzionano le interfacce con metodi virtuali ovvero senza codice, e
poi personalemente non mi sembra che sia molto chiaro.
Ciao e grazie tante, David.

 lo dovro richiamare con objMain.Apri( )  ????
[SNIP]
No alla prima, si alla seconda:
Quando implementi l'interfaccia lMain nella classe fMain non puoi non creare
il metodo Apri; vengono creati tutti automaticamente non appena usi la
keyword 'Implements', nella finestra di codice di fMain li vedi come
Public Sub lMain_Apri()
ecc. dall'esterno invece li vedi come metoti "diretti" della classe fMain
(quindi non si usa "fMain.lMain_Apri" ma il normale "fMain.Apri")
in sostanza:
- se lasci il codice vuoto, la chiamata a fMain.Apri non esegue nulla; e'
proprio qui il nocciolo della questione: non viene ereditato il metodo base,
se vuoi devi farlo tu, a mano e per ogni singolo metodo, con il sistema qui
sotto....
- se vuoi richiamare solo il metodo base
Public Sub lMain_Apri()
objMain.Apri
End Sub
- se vuoi usare una diversa implementazione per la classe figlia
Public Sub lMain_Apri()
'solo il tuo codice
End Sub
- se vuoi usare il metodo base *e* del codice specifico per la classe
figlia, metti insieme il tuo codice e la chiamata alla classe base
Spero di avere chiarito un po' meglio la faccenda


Ciao
Adesso ho capito, grazie tante.
Ciao.
David