Vai al contenuto

Costruttori e this

In questa lezione impari a

  • capire cosa sono i costruttori e a cosa servono
  • creare costruttori personalizzati
  • usare l'overloading dei costruttori
  • comprendere la parola chiave this
  • distinguere tra costruttore e metodo normale

Cos'è un costruttore?

Un costruttore è un metodo speciale che viene chiamato automaticamente quando creiamo un nuovo oggetto con new.

Serve per inizializzare gli attributi dell'oggetto al momento della creazione.

Problema senza costruttore

Nella lezione precedente, inizializzavamo gli oggetti così:

Studente studente1 = new Studente();
studente1.nome = "Mario";
studente1.cognome = "Rossi";
studente1.eta = 17;
studente1.mediaVoti = 7.5;

Attenzione: problemi di questo approccio.

  • Molte righe di codice ripetitive
  • Possiamo dimenticare di inizializzare alcuni attributi
  • Rischio di errori se sbagliamo a scrivere il nome
  • Codice poco elegante e meno manutenibile

Soluzione: il costruttore

Con un costruttore, possiamo fare tutto in una riga:

Studente studente1 = new Studente("Mario", "Rossi", 17, 7.5);

Sintassi del costruttore

Caratteristiche di un costruttore.

  • Ha lo stesso nome della classe
  • NON ha tipo di ritorno (nemmeno void)
  • Può avere parametri (o nessuno)
  • Viene chiamato automaticamente con new

Classe Studente con costruttore

public class Studente {
    // Attributi
    String nome;
    String cognome;
    int eta;
    double mediaVoti;
    
    // COSTRUTTORE
    public Studente(String n, String c, int e, double m) {
        nome = n;
        cognome = c;
        eta = e;
        mediaVoti = m;
    }
    
    // Metodi
    void stampaInfo() {
        System.out.println("Nome: " + nome + " " + cognome);
        System.out.println("Età: " + eta);
        System.out.println("Media: " + mediaVoti);
    }
    
    boolean ePromosso() {
        return mediaVoti >= 6.0;
    }
}

Uso del costruttore

public class TestStudente {
    public static void main(String[] args) {
        // Creo oggetti usando il costruttore
        Studente s1 = new Studente("Mario", "Rossi", 17, 7.5);
        Studente s2 = new Studente("Giulia", "Bianchi", 16, 8.2);
        Studente s3 = new Studente("Luca", "Verdi", 17, 5.8);
        
        // Stampo le informazioni
        s1.stampaInfo();
        System.out.println("Promosso: " + s1.ePromosso());
        System.out.println();
        
        s2.stampaInfo();
        System.out.println("Promosso: " + s2.ePromosso());
        System.out.println();
        
        s3.stampaInfo();
        System.out.println("Promosso: " + s3.ePromosso());
    }
}
Nome: Mario Rossi
Età: 17
Media: 7.5
Promosso: true

Nome: Giulia Bianchi
Età: 16
Media: 8.2
Promosso: true

Nome: Luca Verdi
Età: 17
Media: 5.8
Promosso: false

La parola chiave THIS

this è un riferimento all'oggetto corrente, cioè l'oggetto su cui stiamo lavorando in quel momento.

Si usa principalmente quando il nome del parametro è uguale al nome dell'attributo.

Costruttore con this

Vediamo come migliorare il costruttore usando this:

public class Studente {
    // Attributi
    String nome;
    String cognome;
    int eta;
    double mediaVoti;
    
    // COSTRUTTORE CON THIS
    public Studente(String nome, String cognome, int eta, double mediaVoti) {
        // this.nome si riferisce all'attributo della classe
        // nome (senza this) si riferisce al parametro
        this.nome = nome;
        this.cognome = cognome;
        this.eta = eta;
        this.mediaVoti = mediaVoti;
    }
    
    void stampaInfo() {
        System.out.println("Nome: " + this.nome + " " + this.cognome);
        System.out.println("Età: " + this.eta);
        System.out.println("Media: " + this.mediaVoti);
    }
}

Vantaggi di usare this.

  • Possiamo usare nomi più chiari per i parametri
  • Evitiamo confusione tra attributi e parametri
  • Il codice è più leggibile

Overloading dei costruttori

L'overloading significa creare più costruttori con parametri diversi.

Java sceglie automaticamente quale costruttore usare in base ai parametri che passiamo!

Esempio di overloading

public class Libro {
    String titolo;
    String autore;
    int pagine;
    double prezzo;
    
    // Costruttore 1: tutti i parametri
    public Libro(String titolo, String autore, int pagine, double prezzo) {
        this.titolo = titolo;
        this.autore = autore;
        this.pagine = pagine;
        this.prezzo = prezzo;
    }
    
    // Costruttore 2: solo titolo e autore
    public Libro(String titolo, String autore) {
        this.titolo = titolo;
        this.autore = autore;
        this.pagine = 0;      // Valore di default
        this.prezzo = 0.0;    // Valore di default
    }
    
    // Costruttore 3: solo titolo
    public Libro(String titolo) {
        this.titolo = titolo;
        this.autore = "Sconosciuto";
        this.pagine = 0;
        this.prezzo = 0.0;
    }
    
    // Costruttore 4: senza parametri (costruttore di default)
    public Libro() {
        this.titolo = "Da definire";
        this.autore = "Da definire";
        this.pagine = 0;
        this.prezzo = 0.0;
    }
    
    void stampaInfo() {
        System.out.println("Titolo: " + titolo);
        System.out.println("Autore: " + autore);
        System.out.println("Pagine: " + pagine);
        System.out.println("Prezzo: €" + prezzo);
        System.out.println("---");
    }
}

Uso dei diversi costruttori

public class TestLibro {
    public static void main(String[] args) {
        // Uso costruttore con tutti i parametri
        Libro libro1 = new Libro("1984", "George Orwell", 328, 12.50);
        
        // Uso costruttore con titolo e autore
        Libro libro2 = new Libro("Il Signore degli Anelli", "J.R.R. Tolkien");
        
        // Uso costruttore con solo titolo
        Libro libro3 = new Libro("Harry Potter");
        
        // Uso costruttore senza parametri
        Libro libro4 = new Libro();
        
        libro1.stampaInfo();
        libro2.stampaInfo();
        libro3.stampaInfo();
        libro4.stampaInfo();
    }
}
Titolo: 1984
Autore: George Orwell
Pagine: 328
Prezzo: €12.5
---
Titolo: Il Signore degli Anelli
Autore: J.R.R. Tolkien
Pagine: 0
Prezzo: €0.0
---
Titolo: Harry Potter
Autore: Sconosciuto
Pagine: 0
Prezzo: €0.0
---
Titolo: Da definire
Autore: Da definire
Pagine: 0
Prezzo: €0.0
---

Chiamare un costruttore da un altro

Possiamo usare this() per chiamare un altro costruttore della stessa classe:

public class Libro {
    String titolo;
    String autore;
    int pagine;
    double prezzo;
    
    // Costruttore principale
    public Libro(String titolo, String autore, int pagine, double prezzo) {
        this.titolo = titolo;
        this.autore = autore;
        this.pagine = pagine;
        this.prezzo = prezzo;
    }
    
    // Costruttore che chiama quello principale
    public Libro(String titolo, String autore) {
        this(titolo, autore, 0, 0.0);  // Chiama il costruttore sopra
    }
    
    // Costruttore che chiama quello con 2 parametri
    public Libro(String titolo) {
        this(titolo, "Sconosciuto");  // Chiama il costruttore sopra
    }
    
    // Costruttore che chiama quello con 1 parametro
    public Libro() {
        this("Da definire");  // Chiama il costruttore sopra
    }
}

Vantaggi.

  • Evita duplicazione di codice
  • Più facile da manutenere
  • Se cambio la logica, la cambio in un solo posto

Attenzione. La chiamata this() deve essere la prima istruzione nel costruttore!

Esempio completo: classe Auto

public class Auto {
    String marca;
    String modello;
    int anno;
    double chilometraggio;
    String colore;
    
    // Costruttore completo
    public Auto(String marca, String modello, int anno, 
                double chilometraggio, String colore) {
        this.marca = marca;
        this.modello = modello;
        this.anno = anno;
        this.chilometraggio = chilometraggio;
        this.colore = colore;
    }
    
    // Costruttore per auto nuova (km = 0)
    public Auto(String marca, String modello, int anno, String colore) {
        this(marca, modello, anno, 0.0, colore);
    }
    
    // Costruttore base
    public Auto(String marca, String modello) {
        this(marca, modello, 2024, "Bianco");
    }
    
    void stampaInfo() {
        System.out.println("=== Auto ===");
        System.out.println("Marca: " + this.marca);
        System.out.println("Modello: " + this.modello);
        System.out.println("Anno: " + this.anno);
        System.out.println("Km: " + this.chilometraggio);
        System.out.println("Colore: " + this.colore);
        System.out.println();
    }
    
    void percorri(double km) {
        this.chilometraggio += km;
        System.out.println("Hai percorso " + km + " km. " +
                         "Totale: " + this.chilometraggio + " km");
    }
}
public class TestAuto {
    public static void main(String[] args) {
        Auto auto1 = new Auto("Fiat", "500", 2020, 45000, "Rosso");
        Auto auto2 = new Auto("Toyota", "Yaris", 2023, "Blu");
        Auto auto3 = new Auto("BMW", "X3");
        
        auto1.stampaInfo();
        auto2.stampaInfo();
        auto3.stampaInfo();
        
        auto3.percorri(150);
        auto3.percorri(200);
    }
}
=== Auto ===
Marca: Fiat
Modello: 500
Anno: 2020
Km: 45000.0
Colore: Rosso

=== Auto ===
Marca: Toyota
Modello: Yaris
Anno: 2023
Km: 0.0
Colore: Blu

=== Auto ===
Marca: BMW
Modello: X3
Anno: 2024
Km: 0.0
Colore: Bianco

Hai percorso 150.0 km. Totale: 150.0 km
Hai percorso 200.0 km. Totale: 350.0 km

Esercizi guidati

⭐ Facile

Esercizio 1 – classe Persona con costruttori.

Obiettivo: Creare una classe Persona con più costruttori.

Requisiti:

  1. Attributi: nome, cognome, eta, citta
  2. Costruttore con tutti i parametri
  3. Costruttore con nome, cognome, eta (città = "Non specificata")
  4. Costruttore con nome, cognome (eta = 0, città = "Non specificata")
  5. Metodo stampaInfo()

Codice iniziale:

public class Persona {
    String nome;
    String cognome;
    int eta;
    String citta;
    
    // Costruttore completo
    public Persona(String nome, String cognome, int eta, String citta) {
        // Completa usando this
    }
    
    // Costruttore senza città
    public Persona(String nome, String cognome, int eta) {
        // Completa chiamando l'altro costruttore con this()
    }
    
    // Costruttore solo nome e cognome
    public Persona(String nome, String cognome) {
        // Completa
    }
    
    void stampaInfo() {
        // Completa
    }
}

⭐⭐ Medio

Esercizio 2 – classe punto2D.

Obiettivo: Creare una classe per rappresentare un punto nel piano cartesiano.

Requisiti:

  • Attributi: x (double), y (double)
  • Costruttore con x e y
  • Costruttore senza parametri (origine: x=0, y=0)
  • Metodo distanzaDaOrigine() che restituisce la distanza dall'origine usando il teorema di Pitagora: √(x² + y²)
  • Metodo distanzaDa(Punto2D altro) che calcola la distanza da un altro punto
  • Metodo stampa() che mostra le coordinate

Suggerimenti:

  • Usa Math.sqrt() per la radice quadrata
  • Usa Math.pow(x, 2) per elevare al quadrato

Esercizi da svolgere

⭐⭐ Medio

Esercizio 3 – classe ContoBancario.

Crea una classe ContoBancario con:

  • Attributi: numeroConto, intestatario, saldo
  • Costruttore con numeroConto e intestatario (saldo iniziale = 0)
  • Costruttore con numeroConto, intestatario e saldo iniziale
  • Metodi: deposita(), preleva(), visualizzaSaldo()

⭐ Facile

Esercizio 4 – classe film.

Crea una classe Film con:

  • Attributi: titolo, regista, anno, durata (in minuti)
  • Tre costruttori diversi con livelli crescenti di dettaglio
  • Metodo per convertire la durata in ore e minuti
  • Metodo per stampare tutte le informazioni

⭐⭐ Medio

Esercizio 5 – classe Rettangolo.

Crea una classe Rettangolo con:

  • Attributi: base, altezza
  • Costruttore con base e altezza
  • Costruttore che crea un quadrato (un solo parametro lato)
  • Costruttore senza parametri (rettangolo 1x1)
  • Metodi: calcolaArea(), calcolaPerimetro(), eQuadrato()

⭐ Facile

Esercizio 6 – classe Cerchio.

Crea una classe Cerchio con:

  • Attributo: raggio
  • Costruttore con il raggio
  • Costruttore senza parametri (raggio = 1)
  • Metodo per calcolare area e circonferenza

Concetti chiave da ricordare

  • Il costruttore inizializza gli attributi quando creiamo un oggetto
  • Il costruttore ha lo stesso nome della classe e NO tipo di ritorno
  • this si riferisce all'oggetto corrente
  • Possiamo creare più costruttori con parametri diversi (overloading)
  • this() chiama un altro costruttore (deve essere la prima istruzione)
  • Se non creiamo nessun costruttore, Java ne crea uno vuoto di default

Confronto: costruttore vs metodo

Caratteristica Costruttore Metodo
Nome Stesso nome della classe Qualsiasi nome
Tipo di ritorno NESSUNO (nemmeno void) void o un tipo specifico
Chiamata Automatica con new Manuale con nomeOggetto.metodo()
Scopo Inizializzare l'oggetto Eseguire operazioni