Programmazione ad oggetti (lezione tipo)
Informazioni Generali sulla Lezione
- Materia: Informatica / Ingegneria del Software
- Modulo: Programmazione Orientata agli Oggetti (OOP)
- Livello: Intermedio (Scuola Secondaria di II Grado / Corsi Universitari / Academy)
- Prerequisiti: Concetti base di programmazione strutturata (variabili, tipi di dato, funzioni/procedure, costrutti condizionali ed iterativi).
- Obiettivi Didattici:
- Comprendere il paradigma ad oggetti come strumento di modellizzazione della realtà.
- Identificare e strutturare entità concrete e astratte in Proprietà, Metodi ed Eventi.
- Padroneggiare la distinzione concettuale e di memoria tra Classe e Istanza.
- Analizzare in dettaglio la struttura e il ruolo fondamentale del Metodo Costruttore.
- Saper scrivere e confrontare codice orientato agli oggetti in Java e JavaScript (ES6).
TRASCRIZIONE E TESTO GUIDA DELLA LEZIONE
INTRODUZIONE E PRESENTAZIONE DEL CORSO
"Buongiorno a tutti e benvenuti a questa lezione fondamentale sul paradigma di Programmazione Orientata agli Oggetti, nota con l'acronimo inglese OOP (Object-Oriented Programming).
Fino ad oggi abbiamo scritto codice strutturato: sequenze di istruzioni, cicli e funzioni separate dai dati. Tuttavia, quando i sistemi software diventano complessi, dividere rigidamente dati e funzioni crea problemi di manutenzione. L'OOP nasce negli anni '60 e si afferma dagli anni '80 proprio per superare questo limite, proponendo un approccio intuitivo: modellare il software a partire dagli oggetti della realtà.
Oggi capiremo come trasformare entità reali o concettuali in codice sorgente, analizzando la differenza tra classe e istanza e studiando da vicino il meccanismo di creazione degli oggetti: il Metodo Costruttore."
MODULO 1: MODELLIZZARE IL MONDO: OGGETTI CONCRETI E ASTRATTI
"Iniziamo dalla prima domanda: cos'è un oggetto nel software? Un oggetto è una struttura dati complessa che raggruppa in un'unica entità sia lo stato (i dati) sia il comportamento (le operazioni).
Gli oggetti si dividono in due grandi categorie:
- Oggetti Concreti: Rappresentano entità fisiche e tangibili del mondo reale (es. una Macchina, un Smartphone, un Termostato).
- Oggetti Astratti: Rappresentano concetti, processi o entità logiche che esistono solo all'interno del sistema informatico (es. un Conto Corrente, una Sessione Utente, una Prenotazione, una Transazione).*
Indipendentemente dal fatto che l'oggetto sia concreto o astratto, per modellarlo correttamente dobbiamo descriverlo attraverso tre elementi chiave:
- Proprietà (o Attributi): Rappresentano lo stato dell'oggetto. Rispondono alla domanda: 'Com'è fatto? Quali dati contiene?'
- Metodi: Rappresentano il comportamento dell'oggetto. Rispondono alla domanda: 'Cosa può fare? Quali azioni compie?'
- Eventi: Rappresentano le reazioni dell'oggetto a sollecitazioni interne o esterne. Rispondono alla domanda: 'Cosa succede quando scatta una determinata condizione?'"*
Tabella 1: Analisi comparativa di Modellizzazione (Concreto vs Astratto)
Tipologia OggettoEntità Reale / ConcettoProprietà (Stato)Metodi (Comportamento)Eventi (Reattività)ConcretoSmartphonemarca, modello, percentualeBatteria, isAccesoaccendi(), scattaFoto(), ricarica()onBatteriaScarica, onChiamataInArrivoConcretoTermostato SmarttemperaturaRilevata, temperaturaTarget, modalitàimpostaTemperatura(), attivaRiscaldamento()onSogliaSuperata, onConnessionePersaAstrattoConto CorrentenumeroConto, titolare, saldo, fidoAmmessodeposita(), preleva(), calcolaInteressi()onSaldoInRosso, onTransazioneAnomalaAstrattoSessione UtenteidSessione, utentelogato, oraInizio, indirizzoIPvalidaToken(), rinnova(), chiudiSessione()onTimeoutSessione, onAccessoNegato
Esempio Integrativo di Approfondimento: Il Termostato Smart
"Facciamo un esempio pratico sul Termostato Smart:
- Le sue proprietà saranno
temperaturaAttuale = 21.5eriscaldamentoAcceso = false.* - Il suo metodo
impostaTemperatura(23.0)modificherà lo stato.* - Se la temperatura scende sotto i 18°C, l'oggetto scatena l'evento
onTemperaturaCritica, il quale notificherà la caldaia per avviarla.*
Notate come dati, azioni e segnali siano racchiusi all'interno dello stesso blocco razionale: questo principio prende il nome di Incapsulamento."
MODULO 2: DALLA CLASSE ALL'ISTANZA (IL CONCETTO DI ISTANZA)
"Passiamo ora ad una distinzione concettuale cruciale, fonte di frequente confusione per chi comincia: la differenza tra Classe e Istanza.
Usiamo un'analogia con l'architettura:
- La Classe è il progetto architettonico (il blueprint). Non ci si può abitare dentro; è una descrizione cartacea o digitale che definisce le caratteristiche della casa (numero di stanze, altezza, tipo di impianti).*
- L'Istanza è la casa reale ed edificata in mattoni e cemento. Occupa uno spazio fisico nel mondo (o, nel nostro caso, uno spazio di memoria RAM).*
Da un singolo progetto (Classe) possiamo edificare centinaia di case (Istanze), ciascuna con un indirizzo unico, un colore di pareti diverso o un proprietario differente, ma tutte realizzate secondo la medesima struttura base."
Tabella 2: Confronto Sintetico: Classe vs Istanza
CaratteristicaClasse (Blueprint)Istanza (Oggetto Reale)NaturaConcetto astratto, tipo di dato personalizzato.Entità concreta caricata in memoria.Occupazione MemoriaOccupa memoria minima solo per la definizione del codice.Occupa spazio effettivo nella memoria Heap per memorizzare lo stato dei dati.EsistenzaDefinita a tempo di compilazione / scrittura codice.Creata dinamicamente a tempo di esecuzione (Runtime).Operatore di CreazioneParola chiave class.Parola chiave new (in gran parte dei linguaggi).EsempioAutomobilemiaAuto (Fiat Panda Rossa), autoAziendale (BMW Nera).
MODULO 3: IL METODO COSTRUTTORE IN DETTAGLIO
"Come si passa quindi dal progetto (Classe) all'oggetto concreto (Istanza)? Attraverso un metodo speciale: il Metodo Costruttore.
Il costruttore è un blocco di codice speciale che viene invocato automaticamente ogni volta che si crea una nuova istanza con l'operatore new.I suoi scopi principali sono due:
- Allocare lo spazio in memoria necessario per l'oggetto.
- Inizializzare lo stato iniziale delle sue proprietà, garantendo che l'oggetto nasca in uno stato valido e coerente."*
Regole Fondamentali del Costruttore
- Nome: In linguaggi come Java o C++, il costruttore ha lo stesso identico nome della classe. In JavaScript o Python ha un nome riservato (es.
constructorin JS,__init__in Python). - Nessun Tipo di Ritorno: Il costruttore non restituisce mai un valore explicit (non ha
void,int,String), perché restituisce sempre implicitamente il riferimento alla nuova istanza creata. - Uso della parola chiave
this: All'interno del costruttore, la parola chiavethisindica "l'istanza corrente che si sta creando in questo momento". Serve a distinguere i parametri ricevuti dall'esterno dalle proprietà interne dell'oggetto.
Tabella 3: Costruttore vs Metodo Ordinario
CaratteristicaMetodo CostruttoreMetodo OrdinarioInvocazioneAutomatica tramite operatore new.Esplicita tramite chiamata (oggetto.metodo()).Scopo PrimarioInizializzare lo stato dell'oggetto.Eseguire un calcolo o una funzionalità specifica.Valore di RitornoNessuno (restituisce l'istanza stessa).Obbligatorio (specifico tipo di dato o void).Overloading (Sovraccarico)Supportato (possiamo avere più costruttori con parametri differenti).Supportato nella maggior parte dei linguaggi fortemente tipizzati.
MODULO 4: IMPLEMENTAZIONE PRATICA E CONFRONTO (JAVA VS JAVASCRIPT)
"Vediamo ora come questi concetti teorici prendono forma nel codice sorgente. Mettiamo a confronto due dei linguaggi più usati al mondo: Java (linguaggio fortemente tipizzato basato su classi) e JavaScript (linguaggio a tipizzazione dinamica, che usa la sintassi delle classi dal 2015 con la specifica ES6)."
1. Esempio in JAVA: Modellizzazione di un ContoBancario
Nello scenario Java creiamo la classe ContoBancario. Mostriamo il fenomeno dell'Overloading dei costruttori (più costruttori nella stessa classe) e l'incapsulamento dei dati.
Java
public class ContoBancario {
// 1. PROPRIETÀ (Attributi privati per garantire l'incapsulamento)
private String titolare;
private String iban;
private double saldo;
// 2. COSTRUTTORE 1: Parametrizzato Completo
public ContoBancario(String titolare, String iban, double saldoIniziale) {
this.titolare = titolare;
this.iban = iban;
// Controllo di validità iniziale
if (saldoIniziale >= 0) {
this.saldo = saldoIniziale;
} else {
this.saldo = 0.0;
System.out.println("Attenzione: Saldo iniziale negativo non valido. Impostato a 0.0");
}
}
// 3. COSTRUTTORE 2 (Overloading): Senza saldo iniziale (default a 0)
public ContoBancario(String titolare, String iban) {
this(titolare, iban, 0.0); // Richiama il primo costruttore
}
// 4. METODI (Comportamento)
public void deposita(double importo) {
if (importo > 0) {
this.saldo += importo;
System.out.println("Deposito eseguito. Nuovo saldo: €" + this.saldo);
}
}
public boolean preleva(double importo) {
if (importo > 0 && this.saldo >= importo) {
this.saldo -= importo;
System.out.println("Prelievo eseguito. Saldo residuo: €" + this.saldo);
return true;
} else {
System.out.println("Prelievo fallito: Fondi insufficienti!");
return false;
}
}
// Getter per accedere in sola lettura alle proprietà
public double getSaldo() {
return this.saldo;
}
}
// === CLASSE DI TEST (MAIN) ===
public class Main {
public static void main(String[] args) {
// Creazione dell'ISTANZA 1 con il primo costruttore
ContoBancario contoMario = new ContoBancario("Mario Rossi", "IT99A1234567890", 500.0);
// Creazione dell'ISTANZA 2 con il secondo costruttore
ContoBancario contoLuigi = new ContoBancario("Luigi Bianchi", "IT88B0987654321");
// Uso dei metodi
contoMario.deposita(200.0);
contoLuigi.preleva(50.0); // Fallirà perché il saldo iniziale è 0
}
}
2. Esempio in JAVASCRIPT (ES6): Modellizzazione di un RiproduttoreMusicale con Gestione Eventi
In JavaScript visualizziamo sia proprietà e metodi sia l'integrazione di un Evento (callback).
JavaScript
class RiproduttoreMusicale {
// 1. METODO COSTRUTTORE
constructor(nomeDispositivo) {
// Proprietà
this.nomeDispositivo = nomeDispositivo;
this.branoCorrente = null;
this.inRiproduzione = false;
this.volume = 50; // Valore di default
// Proprietà per la gestione degli EVENTI (Callback)
this.onBranoCambiato = null; // Evento scatenato al cambio brano
}
// 2. METODI
caricaBrano(titoloBrano) {
this.branoCorrente = titoloBrano;
console.log(`[${this.nomeDispositivo}] Caricato brano: "${titoloBrano}"`);
// SCATENAMENTO DELL'EVENTO (Se è stato registrato un gestore)
if (typeof this.onBranoCambiato === 'function') {
this.onBranoCambiato(this.branoCorrente);
}
}
play() {
if (this.branoCorrente) {
this.inRiproduzione = true;
console.log(`[${this.nomeDispositivo}] Riproduzione avviata: "${this.branoCorrente}"`);
} else {
console.log(`[${this.nomeDispositivo}] Impossibile avviare: Nessun brano caricato.`);
}
}
stop() {
this.inRiproduzione = false;
console.log(`[${this.nomeDispositivo}] Riproduzione fermata.`);
}
}
// === UTILIZZO PRATICO (ISTANZE ED EVENTI) ===
// Creazione Istanza 1
const mioPlayer = new RiproduttoreMusicale("Cassa Bluetooth Salotto");
// REGISTRAZIONE DELL'EVENTO
mioPlayer.onBranoCambiato = function(nuovoTitolo) {
console.log(`>>> NOTIFICA EVENTO: Lo schermo aggiorna il titolo visualizzato in: "${nuovoTitolo}"`);
};
// Invocazione metodi
mioPlayer.caricaBrano("Bohemian Rhapsody - Queen");
mioPlayer.play();
mioPlayer.stop();
Tabella 4: Confronto tra Java e JavaScript nella gestione OOP
FunzionalitàJavaJavaScript (ES6+)TipizzazioneFortemente tipizzata (gli attributi richiedono un tipo esplicito).Dinamica (non si dichiarano i tipi delle variabili).Sintassi CostruttoreNome della classe (es. public ContoBancario()).Parola chiave fissa constructor().Overloading CostruttoriNativamente supportato (più costruttori con firme diverse).Non supportato direttamente (si gestisce tramite parametri opzionali o di default).Visibilità (Incapsulamento)Keywords esplicite (private, protected, public).Campi privati introdotti con # (es. #saldo), altrimenti pubblici.Gestione EventiTramite Interfaccia / Listener / Pattern Observer.Tramite funzioni Callback, EventTarget o CustomEvents.
MODULO 5: ESERCITAZIONI GUIDATE E VERIFICA DIDATTICA
"Per consolidare quanto appreso, svolgiamo due esercitazioni pratiche ed un test di verifica rapido."
Esercizio Pratico 1: Modellizzazione Architetturale (Lavoro Indipendente o a Coppie)
Traccia: Modellare il sistema software per una Stazione di Ricarica per Veicoli Elettrici.
- Identificare 3 Proprietà (con tipologia di dato).
- Identificare 2 Metodi con relativi parametri e valori di ritorno.
- Identificare 1 Evento e descrivere la condizione in cui viene scatenato.
- Disegnare una tabella della classe e scrivere il corrispondente costruttore in Java o JavaScript.
Soluzione Proposta Esercizio 1:
- Nome Classe:
StazioneRicarica - Proprietà:
idStazione(Stringa)potenzaMaxKW(Numero Float)isOccupata(Booleano)kWhErogatiTotali(Numero Float)- Metodi:
avviaRicarica(idVeicolo)$\rightarrow$ ImpostaisOccupata = true.interrompiRicarica()$\rightarrow$ Calcola il costo totale ed impostaisOccupata = false.- Evento:
onRicaricaCompletata$\rightarrow$ Scattato automaticamente quando la batteria del veicolo raggiunge il 100%.
Esercizio Pratico 2: Trova l'Errore nel Codice
Analizzare i seguenti due snippet ed individuare gli errori concettuali o sintattici relativi al costruttore:
Snippet A (Java):
Java
public class Automobila {
private String marca;
// ERRORE QUI!
public void Automobila(String marca) {
this.marca = marca;
}
}
- Errore A: Il costruttore ha un tipo di ritorno
void. In Java, inserendovoid, il compilatore lo considera un metodo ordinario e non un costruttore. Di conseguenza, il costruttore di default senza parametri rimarrà attivo e le proprietà non verranno inizializzate correttamente connew Automobila("Fiat").
Snippet B (JavaScript):
JavaScript
class Utente {
constructor(nome, email) {
nome = nome; // ERRORE QUI!
email = email;
}
}
- Errore B: Mancanza della parola chiave
this.. Senzathis.nome = nome, il codice assegna il parametro a se stesso e non salva il valore nella proprietà dell'istanza. L'oggetto creato avrà le proprietàundefined.
DOMANDE DI VERIFICA (SELF-ASSESSMENT / TEST)
- Che differenza c'è tra un oggetto concreto e un oggetto astratto? Fornisci un esempio per ciascuno.
- Risposta: Un oggetto concreto rappresenta un'entità fisica e tangibile del mondo reale (es. uno Smartphone), mentre un oggetto astratto rappresenta un concetto o processo logico interno al software (es. un Conto Corrente o una Sessione Utente).
- Perché un metodo costruttore non restituisce mai un valore esplicito come
intoString?
- Risposta: Perché il costruttore restituisce implicitamente il riferimento alla nuova istanza dell'oggetto appena creata ed allocata nella memoria Heap.
- Cosa succede in memoria RAM quando usiamo la parola chiave
new?
- Risposta: L'operatore
newalloca una nuova porzione di memoria nell'area Heap, invoca il metodo costruttore per inizializzare le proprietà dell'oggetto e ne restituisce l'indirizzo di memoria.
- In Java è possibile definire più di un costruttore per la stessa classe? Se sì, come si chiama questo concetto?
- Risposta: Sì, è possibile definire più costruttori purché abbiano un numero o tipo di parametri differente. Questo concetto prende il nome di Overloading (Sovraccarico) dei costruttori.
RIASSUNTO FINALE DELLA LEZIONE
"Ricapitoliamo i concetti chiave che dovete portare a casa oggi:
- L'OOP permette di strutturare il codice riflettendo entità reali o astratte.
- Ogni oggetto è caratterizzato da Proprietà (cosa contiene), Metodi (cosa fa) ed Eventi (come reagisce).
- La Classe è lo schema teorico; l'Istanza è l'oggetto reale allocato in memoria.
- Il Costruttore è il punto di ingresso dell'oggetto: crea l'istanza e ne inizializza lo stato in modo sicuro.
Nella prossima lezione esploreremo il concetto di Ereditarietà e Polimorfismo, per capire come far interagire classi diverse tra loro. Buon lavoro e buono studio!
Studio Assistito con l'Intelligenza Artificiale
Vuoi padroneggiare al meglio i concetti di questo articolo? Avvia lo studio assistito per generare riassunti automatici, mappe concettuali o farti interrogare con il metodo socratico.