Corso di Java

Metodi e costruttori IV

 

Nella scorsa lezione abbiamo conosciuto una delle caratteristiche più interessanti ed eleganti di Java: l’overloading dei metodi, in particolare dei metodi costruttori.
Questo aspetto non appesantisce il programmatore con un ulteriore carico di lavoro, perché una volta invocato il metodo, anche se ne esistono diversi con lo stesso nome, il numero e il tipo degli argomenti permettono a Java di invocare automaticamente il metodo corrispondente, e questo vale ovviamente anche nel caso dei costruttori.
L’overloading dei metodi elimina la necessità di metodi completamente differenti che eseguono sostanzialmente lo stesso compito e consentono ai metodi di funzionare in modo differente in base agli argomenti che ricevono.
Occorre notare che Java non considera il tipo di valore restituito come un elemento di distinzione, ragion per cui se si cerca di creare due metodi con la stessa segnatura, ma tipi restituiti diversi, la classe non viene compilata e si ottiene l’errore “Methods can't be redefined with a different return type”.
Una possibilità che nasce dall’overloading è quella di definire dei valori di default per certi attributi.

Potremmo ad es. decidere che sia possibile non specificare esplicitamente i valori relativi all’autoradio e all’antifurto, se entrambi sono presenti nell’oggetto della classe “Automobile” che stiamo istanziando.
Ciò significa che se scrivo l’istruzione:

Automobile auto = new Automobile(“Ferrari”, “Testarossa”, 100, 20, 4.2, 90);


istanzio l’oggetto auto come una Ferrari Testarossa che ha un serbatoio da 100 litri, livello di riserva di 20 litri, percorre 4.2 km con un litro, ha 90 litri di benzina nel serbatoio e contiene sia l’autoradio che l’antifurto (non me ne vogliate se i dati tecnici non corrispondono a verità, ma non sono informato al riguardo: al momento non avevo intenzione di comprarne una!).
Potremmo pensare di implementare questa possibilità, inserendo un altro costruttore come il seguente:

Automobile(String mrc, String mdl, float capSerb, float livRis, float cns,
            float qBenz) {
    marca = mrc;
    modello = mdl;
    capacitaSerbatoio = capSerb;
    livelloRiserva = livRis;
    consumo = cns;
    quantitaBenzina = qBenz;
    autoradio = true;
    antifurto = true;
    }


Questa soluzione è corretta e funziona, tuttavia è poco elegante.

Infatti, sia questo metodo che il costruttore che avevamo originariamente creato per la nostra classe Automobile, compiono esattamente le stesse operazioni.
Per venirci in aiuto in queste situazioni, Java fornisce una sintassi speciale con la quale è possibile richiamare un costruttore dal corpo di un altro costruttore della stessa classe.
Ciò è possibile grazie alla parola chiave this, che viene utilizzata ogni qualvolta ci si riferisce all’oggetto corrente.
Essa può trovarsi:
in notazione puntata per citare un attributo dell’oggetto;
come argomento di un metodo;
come valore restituito dal metodo presente;
nel corpo di un metodo costruttore per invocare un altro costruttore della stessa classe.
Tralasciamo per ora i primi tre casi e concentriamoci su quello che ci interessa, ovvero il quarto.
Il nostro scopo è quello di risparmiare di scrivere più volte le stesse righe di codice, sia per una questione di tempo (e, come sappiamo bene, il tempo è denaro), sia per una questione di manutenibilità e di chiarezza del programma che stiamo scrivendo.

Immaginate quale lavoro potrebbe richiedere rivedere il codice di una classe corposa, magari con decine di attributi e numerosi costruttori, nella quale ci siamo accorti di aver fatto degli errori di inizializzazione!
Sarebbe inoltre scomodo scorrere decine di righe di listato per andare a cercare proprio le righe che ci interessano… e se ce ne dimenticassimo qualcuna?
Come possiamo ben vedere, oltre che una questione di eleganza, è soprattutto una questione di efficienza.
Esaminiamo il corpo del costruttore precedente, modificato utilizzando la parola chiave this:

Automobile(String mrc, String mdl, float capSerb, float livRis, float cns,
            float qBenz) {
    this(mrc, mdl, capSerb, livRis, cns, qBenz, true, true);
    }


Quello che facciamo all’interno di esso è semplicemente richiamare il costruttore completo (quello con 8 parametri), passandogli i 6 valori che abbiamo ricevuto dall’istruzione new, più i 2 che abbiamo assegnato di default.

 

Torna all'indice Generale del corso di Corso di Java di Software Planet