Classi ed Oggetti in Java (Cenni) Richiami • Ruolo delle Classi in Java • Oggetti Ruolo delle classi in Java I programmi in Java consistono di classi. Le classi consentono di definire: • collezioni di procedure stand-alone (metodi statici) • oggetti (tramite variabili e metodi d’istanza, che definiscono il loro stato interno e le operazioni) Le due funzionalita’ possono coesistere all’interno di una stessa classe • Una classe puo’ contenere variabili statiche e d’istanza • Analogo per i metodi Procedure Stand-alone Collezione di metodi statici (non ci sono variabili e metodi d’istanza) public class Num { public static int gcd (int n, int d) { while (n != d) if (n > d) n = n - d; else d = d - n; return n;} public static boolean isPrime (int p) { // implementazione} } Oggetti • Servono per creare nuovi tipi di dato con relative operazioni • Vogliamo realizzare una classe BankAccount i cui oggetti sono dei semplici conti bancari. • Vogliamo le seguenti operazioni depositare denaro prelevare denaro chiedere il saldo corrente Come si procede? • Variabili d’istanza devono modellare lo stato degli oggetti • Metodi d’istanza devono modellare le operazioni richieste • Costruttore (o costruttori) per creare un nuovo oggetto della classe Una possibile implementazione public class BankAccount { public double balance; //il saldo corrente // costruttori public BankAccount(double initial){ balance=initial; } Una possibile implementazione // metodi public void deposit(double amount) { balance = balance + amount; } public void withdraw(double amount) { balance = balance - amount; } public double getBalance() { return balance; } } Variabili d’istanza • Gli oggetti della classe si creano tramite new • Le variabili d’istanza appartengono agli oggetti • Ogni oggetto ha la propria variabile d’istanza balance BankAccount p1= new BankAccount(1000); BankAccount p2=new BankAccount(2000); Come si accede? • Dato che le variabili d’istanza appartengono agli oggetti vi si accede tramite il riferimento all’oggetto (che puo’ anche essere implicito) • Supponiamo per esempio di essere in un metodo esterno alla classe (tipo main) tramite il riferimento all’oggetto BankAccount p1= new BankAccount(1000); BankAccount p2=new BankAccount(2000); if (p1.balance=p2.balance) {…} ATTENZIONE: Specificatore di Accesso • public (si puo’ accedere da qualsiasi metodo della classe o non ) •private (si puo’ accedere solo da metodi della classe) Esempio • Supponiamo che balance sia private allora il seguente accesso dal metodo main non e’ legale (viene rilevato dal compilatore) BankAccount p1= new BankAccount(1000); BankAccount p2=new BankAccount(2000); if (p1.balance=p2.balance) {…} Ruolo di private • Come vedremo e’ consigliabile sempre usare variabili d’istanza private • Impediscono l’accesso diretto allo stato degli oggetti che puo’ essere modificato solo dai suoi metodi d’istanza (tipo per esempio deposit e withdraw) • Creano un incapsulamento degli oggetti (fondamentale per garantirne un corretto funzionamento) Metodi d’istanza • I metodi d’istanza eseguono operazioni su un determinato oggetto (che e’ riferito come this nel suo corpo) • devono essere chiamati con il riferimento all’oggetto (che puo’ anche essere implicito) • per esempio da un metodo esterno alla classe come main BankAccount p1= new BankAccount(1000); BankAccount p2=new BankAccount(2000); p1.deposit(2000); p1.deposit(3000); Specificatori di Accesso • Valgono le stesse regole che per le variabili • I metodi private possono essere chiamati solo dall’interno della classe • Non fanno parte dell’interfaccia pubblica della classe (quindi delle operazioni che puo’ usare un utente del tipo di dato) Metodi e Variabili Statici • Variabili e metodi statici appartengono alla classe in cui sono dichiarati • Sono quindi condivisi tra tutti gli oggetti della classe • A differenza delle variabili e dei metodi di istanza che appartengono agli oggetti (istanze della classe). • Come vedremo nella semantica stanno nell’ambiente delle classi e non nella heap Esempio • Supponiamo di volere modificare BankAccount in modo che ogni conto abbia un codice identificativo unico, diverso dagli altri • Si puo’ utilizzare una variabile statica che mantiene il valore del primo numero intero fresh (non e’ ancora stato assegnato) Una possibile implementazione public class BankAccount { public double balance; //il saldo corrente public int miapassword; //la password public static int password; //la prima password disponibile // costruttori public BankAccount(double initial){ balance=initial; miapassword=password; password++; } • La variabile statica e’ unica e condivisa tra tutti i conti questo garantisce che il valore non sia stato gia’ usato. Specificatori di accesso • Valgono le stesse regole viste per le variabili ed i metodi di istanza Variabili e Metodi Statici: come si accede? • Supponiamo per esempio di essere in un metodo esterno alla classe (tipo main) e che la variabile sia public (anche se non ha senso da un punto di vista di sicurezza) • Come facciamo a riferirci alla variabile password ? Due Modi Possibili • Tramite la classe di appartenenza BankAccount.password=1; •Tramite un oggetto della classe BankAccount p1=new Bankaccount(1000); p1.password=1; •La variabile statica e’ visibile da tutti gli oggetti della classe) Regole di Visibilita’ dei Nomi • Sono quelle verificate staticamente dal compilatore (si chiamano regole di scoping) • Verifica che ogni accesso ad un nome (di variabile o metodo) sia legale, ovvero il legame tra le dichiarazioni e l’uso dei nomi Regole di Visibililita’ dei Nomi • Vediamo le regole di base • Sono un po’ piu’ complicate di quelle che avete visto fino ad ora (erano semplificate a scopo didattico) • Complicate dalla coesistenza di nomi statici e d’istanza • Tralasciando i vincoli imposti dagli specificatori di accesso Cosa e’ visibile da un oggetto? • I suoi nomi d’istanza • I nomi statici dichiarati nella classe a cui appartiene (perche’ sono condivise tra tutti gli oggetti) Cosa e’ visibile da una classe? • I suoi nomi statici • Non sono visibili nomi d’istanza (sono relativi agli oggetti) Metodi • Come facciamo a capire se un accesso del seguente tipo e’ legale? Path.I • Dipende dal Path e dal tipo di metodo (statico o d’istanza) Path Vuoto • Accesso diretto (I) • Vediamo le variabili locali del metodo • Vediamo quello che si vede dalla classe (se il metodo e’ statico) • Vediamo quello che si vede dagli oggetti della classe (se il metodo e’ d’istanza o e’ un costruttore) Esempio public void deposit(double amount) { balance = balance + amount;} public BankAccount(double initial){ balance=initial; miapassword=password; password++; } • Accesso diretto alle variabili d’istanza (this implicito) e a quella statica • Entrambe sono visibili dagli oggetti della classe Path Classe • Vediamo solo quello che si vede dalla classe • Per esempio da main: BankAccount p1=new Bankaccount(1000); BankAccount.password=1; (accesso legale) BankAccount.balance=1; (accesso illegale) Path Oggetto • Vediamo quello che si vede dall’oggetto • Per esempio da main: BankAccount p1=newBankaccount(1000); p1.password=1;(accesso legale) p1.balance=1; (accesso legale)