Programmazione Orientata agli Oggetti (OOP)

Tags
Published
Author

1. Classi e Oggetti

Definizione delle Classi

💡
Una classe è un modello o una struttura che definisce le caratteristiche (variabili di istanza o membri) e i comportamenti (metodi) di un oggetto.
Gli elementi principali di una classe includono:
  • Variabili di Membro: Rappresentano gli attributi di una classe. Ad esempio:
public class Persona { String nome; int età; }
  • Metodi di Membro: Definiscono il comportamento di una classe. Ad esempio:
public void saluta() { System.out.println("Ciao!"); }
  • Costruttori: Inizializzano gli oggetti di una classe. Ad esempio:
public Persona(String nome, int età) { this.nome = nome; this.età = età; }

Creazione degli Oggetti

Gli oggetti vengono creati utilizzando la parola chiave new:
Persona persona = new Persona("Mario", 30);

Memorizzazione degli Oggetti in Memoria

  • Heap: Dove sono memorizzati gli oggetti creati con new.
  • Stack: Dove sono memorizzate le variabili di riferimento agli oggetti.
  • Metaspace: Memorizza informazioni sulle classi.

3. Incapsulamento

Modificatori di Accesso

I modificatori di accesso controllano la visibilità dei membri di una classe:
  • public: Accessibile da qualsiasi classe.
  • protected: Accessibile dalle classi nello stesso package o dalle sottoclassi.
  • default (nessun modificatore): Accessibile solo dalle classi nello stesso package.
  • private: Accessibile solo all'interno della stessa classe.

Getter e Setter

Questi metodi permettono di accedere e modificare i membri privati di una classe:
private String nome; public String getNome() { return nome; } public void setNome(String nome) { this.nome = nome; }

Benefici dell'Incapsulamento

  • Migliora la sicurezza dei dati.
  • Consente di modificare l'implementazione senza cambiare il codice esterno.
  • Facilita il debug e la manutenzione.

4. Ereditarietà

Parola Chiave extends

Permette a una classe di ereditare attributi e metodi da un'altra classe:
public class Studente extends Persona { private String corso; }

Parola Chiave super

  • Costruttori della Classe Padre:
public Studente(String nome, int età, String corso) { super(nome, età); this.corso = corso; }
  • Accesso ai Membri della Classe Padre:
System.out.println(super.nome);

Metodo Override

Consente a una sottoclasse di fornire una nuova implementazione di un metodo della classe padre:
@Override public void saluta() { System.out.println("Ciao, sono uno studente."); }

Regole del Override

  • La firma del metodo deve essere identica.
  • La visibilità non può essere ridotta.
  • Il metodo deve essere dichiarato in una classe padre o interfaccia.

5. Polimorfismo

Concetti di Upcasting e Downcasting

  • Upcasting: Conversione di un oggetto di una sottoclasse in un tipo della classe padre:
    • Persona persona = new Studente();
  • Downcasting: Conversione di un oggetto della classe padre in un tipo della sottoclasse (richiede il controllo del tipo):
    • if (persona instanceof Studente) { Studente studente = (Studente) persona; }

Overload vs Override

  • Overload (Sovraccarico): Stesso nome di metodo, ma firme diverse:
public int somma(int a, int b); public double somma(double a, double b);
  • Override: Stesso nome e firma del metodo della classe padre, con una nuova implementazione.

Binding Dinamico

Consente di determinare quale metodo chiamare a runtime:
Persona persona = new Studente(); persona.saluta(); // Chiama il metodo della sottoclasse

6. Classi Astratte e Interfacce

Parola Chiave abstract

  • Una classe astratta non può essere istanziata.
  • Può contenere metodi astratti (senza implementazione) e metodi concreti (con implementazione):
public abstract class Animale { public abstract void verso(); public void dorme() { System.out.println("Zzz..."); } }

Interfacce

Definiscono un contratto che le classi devono rispettare:
  • Dichiarate con interface.
  • Implementate con implements.
    • public interface Volante { void vola(); } public class Aereo implements Volante { public void vola() { System.out.println("L'aereo vola."); } }

Differenze tra Interfacce e Classi Astratte

  • Le interfacce non possono avere costruttori.
  • Una classe può implementare più interfacce, ma estendere una sola classe astratta.
  • Le interfacce supportano metodi di default a partire da Java 8.

8. Funzioni Lambda e Interfacce Funzionali

Le interfacce funzionali (interfacce con un solo metodo astratto) possono essere utilizzate con espressioni Lambda:
@FunctionalInterface public interface Operazione { int calcola(int a, int b); } Operazione somma = (a, b) -> a + b; System.out.println(somma.calcola(5, 3)); // Output: 8

Back to →
🐚
Java