W3docs

Concetti OOP in Java

Una panoramica della programmazione orientata agli oggetti in Java: incapsulamento, ereditarietà, polimorfismo e astrazione.

La programmazione orientata agli oggetti (OOP) è un modo di organizzare il codice attorno alle cose del programma anziché ai passi. Invece di un lungo script che opera su variabili grezze, si descrivono i tipi di oggetti del dominio — un User, un Order, un BankAccount — e si fornisce a ciascuno i dati e il comportamento necessari. Il resto del programma chiede poi a quegli oggetti di fare cose, invece di accedere direttamente ai loro dettagli interni.

Java è stato costruito attorno a questa idea. Ogni riga di codice Java vive all'interno di una classe, e una classe è il modello da cui vengono creati gli oggetti. Fino a questo punto hai scritto codice per lo più procedurale dentro main e alcuni helper statici; da questa parte del libro in poi, inizierai a progettare classi tue.

Classi e oggetti in una frase

Una classe descrive un tipo di cosa — quali dati contiene e cosa sa fare. Un oggetto è una specifica istanza di quella cosa.

public class Dog {
  String name;
  int age;

  void bark() {
    System.out.println(name + " says woof");
  }
}

Dog d = new Dog();   // d is an object — one specific dog
d.name = "Rex";
d.bark();            // Rex says woof

Dog è la classe. d è un oggetto. Il cambiamento chiave rispetto al codice procedurale: un oggetto raggruppa stato (i campi name e age) e comportamento (il metodo bark()) in un'unica unità. Puoi creare quanti oggetti Dog vuoi; ognuno ottiene la propria copia di name e age, e ognuno può eseguire bark() autonomamente. Il capitolo su classi e oggetti approfondisce questo argomento nel dettaglio.

I quattro pilastri

L'OOP viene solitamente insegnato attorno a quattro concetti. Ognuno ha un capitolo dedicato più avanti in questa parte del libro — ciò che segue è una panoramica rapida per capire dove si arriverà.

Incapsulamento

Tieni i dati di un oggetto privati; esponi invece il comportamento. Il codice esterno chiama account.deposit(50), non account.balance += 50. Il vantaggio è che la classe controlla i propri invarianti — nessun altro può portarla in uno stato errato.

public class Account {
  private int balance;                          // hidden

  public void deposit(int amount) {             // public behavior
    if (amount <= 0) throw new IllegalArgumentException();
    balance += amount;
  }
}

Vedi il capitolo sull'incapsulamento.

Ereditarietà

Una classe può estendere un'altra, ereditando i suoi campi e metodi e aggiungendone di nuovi. Cat extends Animal riutilizza tutto ciò che Animal fa già e specifica solo ciò che è diverso per i gatti.

public class Animal {
  void breathe() { System.out.println("inhale, exhale"); }
}
public class Cat extends Animal {
  void purr()   { System.out.println("rrr"); }
}

Cat c = new Cat();
c.breathe();   // inherited
c.purr();      // own

Vedi il capitolo sull'ereditarietà.

Polimorfismo

La stessa chiamata può fare cose diverse a seconda dell'oggetto effettivo che la riceve. Una variabile di tipo Animal potrebbe puntare a un Cat, un Dog o una Cow — chiamare speak() su di essa sceglie il comportamento corretto a runtime.

Animal a = new Cat();
a.speak();   // calls Cat's speak, even though a is typed as Animal

Vedi il capitolo sul polimorfismo.

Astrazione

Definisci cosa fa qualcosa senza impegnarti su come. Un'interface Shape dice che ogni forma ha un metodo area(); ogni forma concreta — Circle, Square — fornisce la propria formula. Il codice che lavora con le forme non ha bisogno di sapere di quale tipo si tratta.

public interface Shape {
  double area();
}

Vedi il capitolo sull'astrazione.

I pilastri a colpo d'occhio

PilastroIdea in una rigaStrumento Java
IncapsulamentoNascondi i dati, esponi il comportamentocampi private + metodi pubblici
EreditarietàRiutilizza ed estendi un'altra classeextends
PolimorfismoUna chiamata, comportamento scelto a runtimeoverride + variabili di supertipo
AstrazioneDefinisci cosa, non comeinterfacce e classi astratte

I pilastri si sovrappongono intenzionalmente: il polimorfismo si basa sull'ereditarietà, l'astrazione è applicata attraverso l'incapsulamento, e così via. Considerali come quattro angolazioni su un'unica idea — modella il tuo programma come oggetti che cooperano — piuttosto che quattro caratteristiche separate da memorizzare.

Perché farlo?

Per uno script di 20 righe, l'OOP è eccessivo. Il vantaggio emerge man mano che i programmi crescono:

  • Ragionamento locale. Una classe BankAccount possiede le sue regole. Per capire o modificare i depositi, leggi il metodo deposit — non devi cercare in tutto il codebase balance +=.
  • Riuso senza copia-incolla. L'ereditarietà e la composizione consentono a SavingsAccount di basarsi su Account invece di duplicarla.
  • Sostituibilità. Una funzione che accetta una Shape funziona per ogni forma esistente oggi e per ogni nuova che aggiungi domani.
  • Testabilità. Oggetti piccoli con responsabilità chiare sono facili da istanziare, guidare e verificare.

Java è ben lungi dall'essere l'unico linguaggio orientato agli oggetti — Python, C#, Kotlin, Ruby e molti altri condividono le stesse idee con sintassi diverse. Ciò che impari in questa parte si trasferisce.

L'OOP non è l'unico paradigma

Anche all'interno di Java, hai già scritto codice che non è strettamente OO: metodi di utilità statici, aritmetica primitiva, semplice flusso di controllo. Il Java moderno mescola i paradigmi — pipeline funzionali con stream e lambda, dati immutabili con i record, lavoro dichiarativo con le annotazioni. L'OOP è la spina dorsale del linguaggio, non una gabbia. Usa una classe quando stai modellando una cosa con stato e comportamento; usa un metodo statico quando hai bisogno solo di un calcolo.

Un esempio pratico

Il codice completo degli snippet precedenti, messo insieme in modo da poterlo eseguire:

java— editable, runs on the server

Cosa c'è dopo

Ora che conosci la struttura dell'OOP, il prossimo capitolo ne fissa i fondamenti: come una definizione di classe diventa un oggetto in memoria, cosa fa effettivamente new, e come i riferimenti agli oggetti differiscono dai tipi primitivi. Continua con classi e oggetti Java.

Esercitati

Pratica
Quale affermazione descrive meglio la differenza tra una classe e un oggetto?
Quale affermazione descrive meglio la differenza tra una classe e un oggetto?
Was this page helpful?