PROGRAMMAZIONE A OGGETTI (OOP) Lezione 5 prj Mesa (Prof. Ing N. Muto) Approfondimento INCAPSULAZIONE Abbiamo visto nelle lezioni precedenti che i 3 fattori che rendono un linguaggio adatto per lo sviluppo della OOP sono l'INCAPSULAZIONE, l'EREDITARIETA' ed il POLIMORFISMO. In questa lezione approfondiremo i primi due aspetti, utilizzando anche del codice di esempio. Per quanto riguarda l'INCAPSULAZIONE essa è strettamente connessa alla creazione della classe in quanto la classe stessa è un contenitore di codice e variabili, più o meno complesse, atte a contenere le informazioni. Abbiamo poi anche visto che è possibile specificare se un membro della classe (sia metodo che attributo) può essere dichiarato private o public a seconda che lo si voglia rendere visibile e accessibile o meno al resto del codice. Abbiamo poi imparato a conoscere il costruttore della classe che è un metodo che DEVE avere lo stesso nome della classe e che viene chiamato dall'operatore new al momento della creazione dell'oggetto (“instanziazione”). Il codice alla pagina seguente ci aiuterà a ripassare tutto quanto ricordato finora e ci introdurrà ad alcune novità come il distruttore della classe e la tecnica delle funzioni “get e set” per l'accesso controllato a membri privati di una classe. Prima di introdurre tale codice definiamo però il distruttore: esso è un metodo che DEVE avere lo stesso nome della classe preceduto però dal simbolo “~” e non deve avere modificatore di visibilità o accesso (public o private). Il distruttore viene richiamato automaticamente quando l'oggetto non ha più visibilità o viene chiuso il programma. Dovrebbe essere usato per eseguire delle istruzioni di “pulizia” o di chiusura. Per quanto riguarda i metodi “get e set” di cui sopra si tratta come vedremo di un modo controllato di accedere a dati membro dichiarati “private” per sicurezza ma a cui comunque è necessario accedere nel corso dell'elaborazione. Il fatto di accederci tramite delle funzioni della classe è come se non lasciassimo accesso verso tali variabili ma ci arrivassimo dopo aver aperto una porta chiusa normalmente a chiave e quindi otteniamo un accesso “controllato”. L'esempio della classe “Rettangolo” nella pagina seguente chiarisce meglio il tutto. public class Rettangolo { double Base; double Altezza; double Diagonale; public double Perimetro; public double Area; //inizio della classe Rettangolo public Rettangolo() { double Base = 0; double Altezza = 0; double Perimetro = 0; double Area = 0; } ~Rettangolo() { //questo distruttore scrive "Ciao!" Console.WriteLine("Ciao!"); Attributi della classe, notare che Base, Altezza Diagonale sono dichiarati senza modificatori e quindi sono private per default. Invece i metodi Perimetro ed Area sono dichiarati public. Il costruttore non ha parametri e si limita ad inizializzare a zero tutti i dati membro. Notare che ha lo stesso nome della classe ed è dichiarato public. Ecco la nostra nuova conoscenza: il distruttore! A dispetto del suo nome preoccupante, il nostro distruttore non fa niente e si limita a salutare. Notare il carattere “tilde” davanti al nome. } //questa funzione public è necessaria per impostare la variabile Base perché //Base è definita come "private" e NON e' quindi direttamente accessibile public void setBase(double x) Questa funzione dichiarata public è accessibile dall'esterno { della classe ed agisce su un dato membro che in realtà è Base = x; dichiarato private. In questo modo salvaguardiamo la variabile } private da accessi incontrollati ma otteniamo comunque la possibilità di impostarla. public void setAltezza(double x) { Altezza = x; } Stesso discorso per la funzione setAltezza e la relativa variabile private “Altezza” //questa funzione deve essere richiamabile per cui viene dichiarata public public void calcolaPerimetro() { Perimetro = (Base + Altezza) * 2; } //questa funzione deve essere richiamabile per cui viene dichiarata public public void calcolaArea() { Area = Base * Altezza; } //questa funzione public è necessaria per accedere al valore della variabile Perimetro perché //Perimetro è definita come "private" e NON e' quindi direttamente accessibile public double getPerimetro() { return Perimetro; } //questa funzione public è necessaria per accedere al valore della variabile Area perché //Area è definita come "private" e NON e' quindi direttamente accessibile public double getArea() { return Area; } } // fine della classe Rettangolo Per completezza vediamo l'utilizzo della classe suddetta all'interno di un programma reale: namespace ConsoleApplication1 { class Program { static void Main(string[] args) { Rettangolo Rect1 = new Rettangolo(); L'esempio sviluppato è un programma del tipo “Console” ossia senza grafica ma a linea di comando. Questa istruzione crea l'oggetto in base alla ricetta contenuta nella classe “Rettangolo” Console.WriteLine(); Console.WriteLine(" Creato un rettangolo coincidente con un punto:"); Console.WriteLine(" Infatti, Area = {0} Perimetro = {1}", Rect1.getArea(), Rect1.getPerimetro()); Console.WriteLine(); Console.WriteLine(); Console.WriteLine(" Ora impostiamo Base e Altezza usando i metodi set relativi:"); Console.Write(" Inserisci Base: "); Rect1.setBase(Convert.ToDouble(Console.ReadLine())); Console.Write(" Inserisci Altezza: "); Rect1.setAltezza(Convert.ToDouble(Console.ReadLine())); Console.WriteLine(); Console.WriteLine(); Qui vengono impostati Base e Altezza chiedendoli all'utente. Notare l'uso delle funzioni “set” per accedere a membri “private” della classe. Console.WriteLine(" Ora possiamo calcolare l'Area ed il Perimetro e stamparne i valori"); Rect1.calcolaPerimetro(); Rect1.calcolaArea(); Console.WriteLine(" Perimetro: {0} Area: {1}", Rect1.Perimetro, Rect1.Area ); Console.ReadLine(); //Questa istruzione serve a lasciare la finestra di output //aperta finche' non si preme ENTER } } Di seguito riportiamo anche ciò che si vedrà sullo schermo mentre il programma verrà eseguito. All'inizio il programma crea l'oggetto e mostra i valori di Area e Perimetro che sono nulli in quanto tutti i dati membro sono stati inizializzati a zero dal costruttore: Successivamente viene chiesto all'utente di inserire i valori della Base e dell'Altezza del rettangolo, poi vengono chiamati i metodi pubblici per calcolare Perimetro e Area e vengono mostrati a video: Infine, quando il programma viene chiuso, viene richiamato il distruttore che in questo caso mostra solo una scritta sul video: