Costruttori: Inizializzare gli Oggetti
🎯 Obiettivi della lezione
- 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;
⚠️ 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());
}
}
🔑 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();
}
}
🔗 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);
}
}
✏️ Esercizi Guidati
Esercizio 1: Classe Persona con Costruttori
FACILEObiettivo: Creare una classe Persona con più costruttori.
Requisiti:
- Attributi: nome, cognome, eta, citta
- Costruttore con tutti i parametri
- Costruttore con nome, cognome, eta (città = "Non specificata")
- Costruttore con nome, cognome (eta = 0, città = "Non specificata")
- 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
}
}
Esercizio 2: Classe Punto2D
MEDIOObiettivo: 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
Esercizio 3: Classe ContoBancario
MEDIOCrea 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()
Esercizio 4: Classe Film
FACILECrea 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
Esercizio 5: Classe Rettangolo
MEDIOCrea 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()
Esercizio 6: Classe Cerchio
FACILECrea 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 |