86247 Letture

Corso Java - Sesta lezione: ereditarietà, polimorfismo ed eccezioni

Giunti alla sesta puntata del nostro viaggio all'interno di Java, è ora di occuparci di una serie di concetti che renderanno le potenzialità del linguaggio estremamente più elevate rispetto a quelle che conosciamo adesso. Si tratta di concetti strettamente legati al mondo della programmazione ad oggetti. Per introdurli dobbiamo però fare un passo indietro, e parlare dei modificatori di visibilità.

Modificatori di visibilità e modificatore static

In tutti i linguaggi di programmazione ad oggetti esiste un concetto, chiamato scope delle variabili, che per i programmatori non esperti può rivelarsi ostico. Cercheremo pertanto ora di fare un minimo di chiarezza.
Abbiamo imparato fino ad ora a definire variabili e costanti di vario tipo, e abbiamo visto che in Java questo avviene essenzialmente in due modi:
- variabili dichiarate all'interno di metodi
- variabili dichiarate come dati di istanza

Abbiamo anche detto che se abbiamo una classe MyClass che definisce un certo tipo di oggetti, tutti gli oggetti di quella classe avranno "al loro interno" le variabili dichiarate come dati di istanza, mentre le variabili dichiarate nei metodi sono le variabili che utilizziamo per poter implementare le funzionalità degli oggetti, ma in realtà non hanno nessuna particolare pretesa di far parte degli oggetti stessi, e quindi di descriverne in un certo senso lo status. Su tutti questi concetti possono intervenire due tipi di modificatori, i modificatori di visibilità e il modificatore static.
Occupiamoci in primo luogo del modificatore static. La sua funzione differisce a seconda che ci sia posto davanti ad una variabile o ad un metodo, come in questo codice:


public class MyClass{

// dato di istanza NON static
int numero1;
//dato di istanza static
static numero2;

// Il costruttore NON può essere static
public MyClass(){
}

// metodo static
public static void method(){}

}


Occupiamoci in primo luogo del modificatore static posto dinanzi ai dati di istanza. Esso fa in modo che la variabile sia una cosiddetta variabile di classe cioè che venga allocata una sola volta quando si alloca lo spazio per la classe MyClass e non per ogni oggetto, in parole povere non descrive lo stato dell'oggetto ma di una classe. Questo fa sì che il modo per accedervi sia il seguente:

MyClass myObject = MyClass();
// Accesso sbagliato alla variabile numero2, restituisce errore
myObject.numero2 = 3;
// Accesso corretto alla variabile numero2
MyClass.numero2 = 3;


Notate che gli stessi concetti possono essere applicati alle costanti (che ricordiamo essere espresse con il modificatore final in Java) e in effetti questo è uno degli usi più comuni del modificatore static, la definizione di costanti che possano essere quindi accessibili in tutte le parti del programma senza dover dichiarare un oggetto atto a contenerle (operazione che, evidentemente, richiede l'uso di risorse e i programmatori sono in genere restii a utilizzare risorse quando questo si può evitare).

Per quanto riguarda i dati di istanza inoltre, in Java esistono tre diversi modificatori di visibilità e si tratta dei modificatori public, private, protected. Si tratta di tre modifiche effettive, poiché se omettiamo modificatori di visibilità il compilatore assume che esso abbia una visibilità ancora differente da questi. Pur tuttavia per i nostri scopi non ci occuperemo delle piccole differenze che intercorrono tra questa visibilità e la visibilità protected (la più vicina delle tre).
La caratteristica fondamentale che dobbiamo considerare per questi modificatori di visibilità è che i dati di istanza dichiarati public sono direttamente accessibili con la sintassi
MyObject.dato o MyClass.dato (nel caso siano static).
Anche dall'esterno della classe medesima. Ciò significa che se scriviamo

public class MyClass{
private int dato;
...
}

// altra classe public, quindi altro file
public class MySecondClass{

public MySecondClass(){

            MyClass myObject = new MyClass();
            myObject.dato = 4;
}

}


il compilatore ci restituirà un errore dicendo che "dato" non ha visibilità public. Questo sistema garantisce quindi che solo ed esclusivamente un metodo della classe MyClass possa agire sulla variabile dato. Si tratta di un meccanismo fondamentale che permette ad una classe di rispettare i principi detti dell'incapsulamento secondo i quali è buona programmazione non permettere l'accesso diretto alle variabili da parte di altre classi quando questo non è fortemente necessario. Noterete che programmando avrete un irrefrenabile istinto a dichiarare public un gran numero di variabili, tutte quelle cui volete accedere in fase di esecuzione. Si tratta di una pratica fortemente sconsigliata, soprattutto perché rende meno portabile il codice. La soluzione standard per queste situazioni, in Java, è creare due metodi getXXXX e setXXXX che accedano alla variabile in questione, la quale la possiamo dichiarare private o protected (la differenza consiste nel fatto che le variabili protected sono accessibili direttamente da classi dello stesso package, quelle private no). Ad esempio, se abbiamo una variabile

private int numeroSoci;

potremmo scrivere i due metodi seguenti

public int getNumeroSoci(){
return numeroSoci;
}


public void setNumeroSoci(int value){
numeroSoci = value;
}


Si tratta di una metodologia di programmazione molto comune in Java, ampiamente usata anche per costruire il package delle classi standard (ricordo che quando scaricate il j2se c'è un file chiamato src.zip che contiene i sorgenti delle classi java del package standard e che potete rendervi conto di come sono frequenti questi metodi visionando la documentazione). Notate come i metodi sono stati dichiarati public, poiché in questo caso desidero che siano accessibili a tutte le classi, ma avrei potuto dichiararli protected se avessi voluto che fossero usati solo all'interno del package.


  1. Avatar
    SimonaTV
    08/07/2008 21.48.32
    Citazione: Mammifero variabile1;
    Cavallo variabile2 = new Cavallo()
    variabile2 = variabile1;
    Nel codice quotato e presente nella guida in java sezione ereditarietà la seguente assegnazione
    Citazione: variabile2 = variabile1;
    è ASSOLUTAMENTE ERRATA perchè si sta tentando si assegnare un oggetto di tipo supertipo mammifero ad una variabile di tipo sottotipo Cavallo il che è semanticamente errato.

    Questa assegnazione invece è semanticamente corretta!
    Citazione: variabile1 = variabile2;
    CORREGGETEEEEEEEEE!!!!!!!!!
Corso Java - Sesta lezione: ereditarietà, polimorfismo ed eccezioni - IlSoftware.it