
Continua il mio articolo sulla programmazione orientata agli oggetti. Abbiamo definito nei due scorsi articoli cosa è l’ereditarietà e cosa è esattamente una interfaccia e come queste due entità siano in relazione fra loro. Abbiamo però tralasciato alcuni concetti molto importanti della programmazione ad oggetti: cosa è una classe? Come interagiscono tra loro e soprattutto, come si fa ad estendere una classe?
Con i concetti descritti finora, possiamo già dare un significato all’entità “classe“.
Una classe altro non è che l’insieme dei metodi, delle proprietà e degli attributi di un particolare oggetto.
Nella programmazione procedurale, come ad esempio nel C, capitava spesso di trovarsi di fronte a problemi come avere bisogno di una entità in grado di gestire da sola i propri problemi.
Esempio:
Un esempio lampante che mi viene in mente (dovuto probabilmente alle mille ore dedicate all’esame di Reti di Calcolatori), è quello in cui bisognava realizzare una comunicazione con un server nel quale si lavorava con le varie socket e poi bisognava spedire e ricevere dati. Al tempo, per l’esame realizzai un file che aveva i metodi Connect, Send, Receive, CloseConnection (nel caso TCP ovviamente). Questo file lo importavo nel main e tramite quelle 4 funzioni lavoravo direttamente con il server. E se avessi dovuto lavorare con 2 server diversi contemporaneamente? Non potevo di certo usare le stesse funzioni perchè logicamente erano dedicate al primo server e quindi o creavo un thread parallelo (che su windows è un mezzo casino abbastanza complicato), oppure risolvevo creando altre 4 funzioni, Connect2, Send2, Receive2, CloseConnection2, con tutti i problemi che ne derivavano… Ovvero che se avessi dovuto contattare un 3° server sarebbe stata la fine, se poi usavo RPC con tutta la questione dei puntatori sarei completamente collassato a terra. L’esame per fortuna è passato e ora mi dedico al C#, che di questi problemi non ne ha nemmeno l’ombra. Con l’introduzione dei linguaggi a oggetti come Java, Smalltalk, C#, C++ e vari, basta creare una classe (un oggetto, un’entità a sé quindi), che contiene questi 4 metodi, poi creare 4 istanze di questa classe ed il gioco è fatto. In C# questa classe esiste già e si chiama ad esempio TcpClient che guarda caso ha i metodi Connect e Close e un metodo GetStream() che permette di inviare e ricevere i dati dal canale.
C# gestisce egregiamente questa caratteristica, essendo il framework completamente basato e orientato agli oggetti. Infatti, ogni singola classe deriva in maniera diretta o indiretta dalla classe object, anche i numeri interi per capirci. Quindi, fare:
object numeroIntero = 5;
oppure
int numeroIntero = 5;
è esattamente la stessa identica cosa. Utilizzando una tecnica particolare comune a tutti i linguaggi managed (ovvero che si basano su un framework, quindi C#, VB.Net, Java ecc), la Reflection, e richiedendo il tipo di oggetto ad entrambi, in questo modo:
numeroIntero.GetType();
otterremo entrambe le volte System.Int32, che si riferisce appunto ad un numero intero.Ora che abbiamo chiarito a cosa ci riferiamo quando parliamo dell’entità classe, cerchiamo di chiarire meglio come interagiscono tra di loro diverse classi. Ritorniamo perciò al nostro problema iniziale. La prima cosa che balza all’occhio è che esistono 4 tipologie di acceleratore, 1 per ogni tipo di vettura. Visto che ogni acceleratore non ha funzionalità particolari, possiamo definire un enumerativo che li include tutti:
public enum TipoAcceleratore : int {
Tipo1 = 1,
Tipo2 = 2,
Tipo3 = 3,
Tipo4 = 4
}
Un’enumerativo è semplicemente una lista di oggetti, come un’insieme di categorie. L’enumerativo per antonomasia è la settimana:
public enum Settimana : int {
Lunedì = 1,
Martedì = 2,
Mercoledì = 3,
Giovedì = 4,
Venerdì = 5,
Sabato = 6,
Domenica = 7
}
Il nostro enumerativo TipoAcceleratore è definito come estensione della classe Int32, questo perchè in questo modo possiamo passare dal valore numerico dell’enumerativo a quello letterale senza problemi.Diamo ora un senso alla classe MacchinaGenerica che avevamo cominciato a vedere la volta scorsa, inseriamo perciò dei campi, ovvero dei dati appartenenti alla classe stessa:
private TipoAcceleratore _acceleratore = TipoAcceleratore.Tipo1;
private int _valAccelerazione = 0;
private int _curvatura = 0;
private string _nome = "Non ho un nome!";
//questo è il costruttore, ovvero una funzione che viene chiamata non appena viene creata la classe
public MacchinaGenerica(string nome, int accelerazione)
{
Nome = nome;
Acceleratore = (TipoAcceleratore)accelerazione;
}
public string Nome
{
get { return _nome; }
set { _nome = value; }
}
public int Curvatura
{
get { return _curvatura; }
set { _curvatura = value; }
}
public int ValoreAccelerazione
{
get { return _valAccelerazione; }
set { _valAccelerazione = value; }
}
public TipoAcceleratore Acceleratore
{
get { return _acceleratore; }
//il set è definito protetto per non fare modificare il valore dall'esterno
protected set { _acceleratore = value; }
}
C’è un pò di carne al fuoco. Cominciamo subito a vedere il costruttore. Il costruttore è una funzione che viene chiamata (eseguita) non appena viene creata un’istanza della classe, rimanendo nel paragone è un pò ciò che accade non appena viene costruita una vettura, quando il telaio viene marchiato per una ed una volta soltanto. Infatti nel costruttore noi andiamo a definire la tipologia dell’acceleratore, che può essere definito solo in questo momento e mai più, in quanto il set del campo è definito protetto (è un pò come se ogni volta che andassimo ad accendere la macchina potessimo decidere se può accelerare come una Ferrari o come una Cinquecento… non avrebbe senso!). Adesso siamo pronti per vedere un esempio di vettura vera e propria, creiamo perciò la classe Fiat500:
public class Fiat500 : MacchinaGenerica
{
public Fiat500()
: base("Fiat500", 1)
{
}
}
Come vedete è una vera banalità, quindi a voi il compito di creare le altre 3 classi… però non notate nulla? Guardando attentamente, accanto a Fiat500 c’è scritto “: MacchinaGenerica“. Questo è la modalità adottata da C# per indicare che Fiat500 in realtà estende (ovvero è una classe figlia) di MacchinaGenerica, cioè ogni istanza della classe Fiat500 è anche istanza di MacchinaGenerica (attenzione: ma non sempre è anche il contrario!). Come accadeva per object con gli interi infatti, accade che scrivendo:
Fiat500 fiat500 = new Fiat500(); MacchinaGenerica vettura = fiat500;
gli oggetti fiat500 e vettura sono la stessa identica cosa.Nelle prossime lezioni parleremo di alcune proprietà che derivano direttamente da questo discorso, come ad esempio il polimorfismo per citarne una. Oggi vi lascio, buon lavoro!
Mi chiamo Denis Billi, ho 25 anni e sono della provincia di Ravenna. Mi sono laureato nell'estate del 2008 presso la facoltà di Ingegneria Informatica dell'università di Bologna e attualmente sto seguendo i corsi per la Laurea Specialistica in Ingegneria Informatica sempre all'università di Bologna.
Ciao Denis,
sono capitato per caso sul tuo blog navigando per tag.
Io sono proprio agli inizi.
Mi hanno incuriosito i link che hai messo nelle porzioni di codice:
‘view plain’ ‘copy to clipboard’ ‘print’.
Nella versione free dell’account non mi pare di essere autorizzato ad usare javascript, quindi mi chiedevo come hai realizzato quei link.
grazie e a presto
ilmatte
Ciao ilmatte, benvenuto nel mio blog! Effettivamente WordPress limita parecchio le libertà degli utenti, per questo ho intenzione di spostarmi presto su un dominio. Tuttavia contiene alcuni plug-in che permetto di fare certe cose: esattamente come quelli per inserire i video di youtube, esiste un plugin che permette di inserire codice sorgente, poi ci pensa WordPress a formattarlo. Basta inserire il codice tra i tag:
….
e lui farà il resto. E’ una possibilità che esiste da poco comunque.
Torna presto!
Ciao!
Accidenti grazie mille,
risposta preziosissima e ultraveloce!!
provo subito…mi resta la curiosità riguardo al link ‘copy to clipboard’ che non ho mai fatto!
Mi daresti una dritta anche su quello?
grazie
ilmatte
P.S.
tra l’altro grazie a te ho anche scoperto freshy (nei prox giorni lo adotterò)
Ciao di nuovo! Come ho detto prima è una cosa che fa direttamente WordPress, per stavolta non centro nulla
Basta che metti il codice tra i due tag e poi fa tutto lui: formatta e mette i 3 link sopra.
PS: Freshy e bello ma è un pò limitato purtroppo! Ma per un blog va benissimo ed è tra quelli che danno meno problemi, soprattutto con il tagcloud!
Ciao!
rieccomi scusa non avevo capito cosa intendevi,
ora ho capito (anche se non riesco a farlo funzionare, forse non è supportato da tutti i temi).
Ora smetto di infestarti la zona commenti
grazie e ciao
ottimo, lavoro!!!!!
per uno che si sta avvicinando ora alla OOP, è molto utile il tuo tutorial.
Nicola
@nicbua
Grazie! Felice di esserti stato d’aiuto. Fammi sapere che ne pensi anche degli altri articoli se hai tempo.
A presto!
Ciao, stavo cercando una risposta al mio dubbio.
Io lavoro con vb.net, ho esteso la classe textbox con funzioni aggiuntive, e volevo fare in modo che tutte le textbox nel progetto utilizzino la mia classe estesa. e qui la domanda: posso fare in modo che quando viene utilizzata la classe “textbox” originale questi vengano “dirottati” sulla mia classe? spero di essere stato chiaro :) ciao grazie