Docsity
Docsity

Prepara i tuoi esami
Prepara i tuoi esami

Studia grazie alle numerose risorse presenti su Docsity


Ottieni i punti per scaricare
Ottieni i punti per scaricare

Guadagna punti aiutando altri studenti oppure acquistali con un piano Premium


Guide e consigli
Guide e consigli


Classi Interne ed Espressioni Lambda in Java: Guida Dettagliata, Dispense di Programmazione Orientata agli Oggetti

Una panoramica dettagliata delle classi interne e delle espressioni lambda in java, due concetti fondamentali nella programmazione orientata agli oggetti. Esplora le diverse modalità di utilizzo delle classi interne, sia all'interno che all'esterno dei metodi, e le loro caratteristiche principali, come l'accesso all'ambiente della classe esterna. Inoltre, introduce le espressioni lambda, spiegando come semplificano la scrittura di metodi e funzioni, migliorando la leggibilità del codice e facilitando l'iterazione su collezioni. Vengono presentati esempi pratici, tra cui l'implementazione di criteri flessibili per la selezione di membri in un social network, illustrando l'uso di interfacce, classi anonime ed espressioni lambda per risolvere problemi specifici. Infine, il documento affronta le regole di scoping nelle espressioni lambda, evidenziando l'importanza dell'effettiva finalità delle variabili locali dell'ambiente esterno.

Tipologia: Dispense

2024/2025

Caricato il 16/09/2025

federica-de-simone-6
federica-de-simone-6 🇮🇹

5 documenti

1 / 9

Toggle sidebar

Questa pagina non è visibile nell’anteprima

Non perderti parti importanti!

bg1
Classi interne ed espressioni lambda
Classi interne
Le classi interne in Java sono classi definite all’interno di altre classi e
possono essere utilizzate in due modalità principali:
Fuori dai metodi: la classe interna è visibile in tutti i metodi della
classe esterna e, a seconda dello specificatore d’accesso, anche
all’esterno della classe stessa.
All’interno di un metodo: la visibilità è limitata al metodo in cui
è definita.
Le caratteristiche principali delle classi interne includono:
Accesso all’ambiente della classe esterna: i metodi della
classe interna possono accedere alle variabili e ai metodi della
classe esterna.
Se definite in un metodo statico, possono accedere solo a
variabili e metodi statici della classe esterna.
Limitazioni
Le classi interne possono accedere a variabili locali del metodo in cui
sono definite solo se queste:
1. Sono dichiarate final.
2. Oppure, non subiscono modifiche dopo la loro inizializzazione
(opzione introdotta con Java 8).
Questo vincolo è dovuto alla modalità di implementazione delle classi
interne in Java: le variabili locali si trovano nello stack e le classi interne,
che possono sopravvivere oltre l'esecuzione del metodo, accedono a
copie delle variabili salvate nell'heap.
Implementazione delle classi interne
La Java Virtual Machine tratta tutte le classi allo stesso livello,
senza considerare annidamenti.
Il compilatore converte le classi interne in classi standard,
separandole dal file .class principale. Il nome del file delle classi
pf3
pf4
pf5
pf8
pf9

Anteprima parziale del testo

Scarica Classi Interne ed Espressioni Lambda in Java: Guida Dettagliata e più Dispense in PDF di Programmazione Orientata agli Oggetti solo su Docsity!

Classi interne ed espressioni lambda

Classi interne Le classi interne in Java sono classi definite all’interno di altre classi e possono essere utilizzate in due modalità principali:  Fuori dai metodi: la classe interna è visibile in tutti i metodi della classe esterna e, a seconda dello specificatore d’accesso, anche all’esterno della classe stessa.  All’interno di un metodo: la visibilità è limitata al metodo in cui è definita. Le caratteristiche principali delle classi interne includono:  Accesso all’ambiente della classe esterna: i metodi della classe interna possono accedere alle variabili e ai metodi della classe esterna.  Se definite in un metodo statico , possono accedere solo a variabili e metodi statici della classe esterna. Limitazioni Le classi interne possono accedere a variabili locali del metodo in cui sono definite solo se queste:

  1. Sono dichiarate final.
  2. Oppure, non subiscono modifiche dopo la loro inizializzazione (opzione introdotta con Java 8). Questo vincolo è dovuto alla modalità di implementazione delle classi interne in Java: le variabili locali si trovano nello stack e le classi interne, che possono sopravvivere oltre l'esecuzione del metodo, accedono a copie delle variabili salvate nell'heap. Implementazione delle classi interne  La Java Virtual Machine tratta tutte le classi allo stesso livello, senza considerare annidamenti.  Il compilatore converte le classi interne in classi standard , separandole dal file .class principale. Il nome del file delle classi

interne include il nome della classe esterna seguito dal simbolo $ e dal nome della classe interna. Accesso all'ambiente esterno Quando un oggetto di una classe interna è istanziato:  Viene utilizzata una variabile nascosta che contiene un riferimento all’oggetto della classe esterna in cui è definita.  Questo riferimento permette di accedere ai metodi e alle variabili visibili nell’ambiente della classe esterna. Per le classi interne definite all’interno di un metodo:  Le variabili locali utilizzate vengono copiate in variabili di istanza nascoste.  Questo è necessario poiché le variabili locali nello stack non sono direttamente accessibili al di fuori del metodo. Esempio di classe interna Un esempio pratico mostra una classe interna che misura l’area di un rettangolo: class RectangleMeasurer implements Measurer { public double measure(Object aRectangle) { Rectangle r = (Rectangle) aRectangle; return r.getWidth() * r.getHeight(); } } Questa classe interna implementa un'interfaccia per misurare oggetti di tipo Rectangle e può essere usata in metodi per calcolare medie o trovare il massimo. Eventi di temporizzazione La classe Timer di javax.swing consente di generare eventi a intervalli prefissati, utili ad esempio per animazioni. Per gestire questi eventi:  Bisogna definire una classe che implementi l’interfaccia ActionListener.

 Preferire l’importazione di singoli membri statici anziché dell’intera classe. Espressioni Lambda Introdotte in Java 8, le espressioni lambda semplificano la scrittura di metodi o funzioni utilizzate direttamente nel punto in cui sono richieste. Un esempio: (p, q) -> p.set(q); Le espressioni lambda:  Sono associate a interfacce funzionali , che contengono un unico metodo astratto.  Offrono una sintassi più compatta rispetto alla creazione di classi anonime. Vantaggi:  Migliorano la leggibilità del codice.  Sono particolarmente utili nei contesti che richiedono callback o iterazioni su collezioni (es. con Stream API). Problema: Applicazione per un social network L'obiettivo è creare un'applicazione tipo per un social network, in cui un amministratore possa eseguire operazioni (ad esempio, inviare email) su membri che soddisfano specifici criteri. La sfida principale riguarda come implementare criteri flessibili e riutilizzabili per selezionare i membri Codice base per la gestione dei membri  È fornita una classe Person che rappresenta i membri, con attributi come nome, data di nascita, genere, e indirizzo email.  Gli oggetti Person vengono memorizzati in un'ArrayList. Classe Person:

public class Person { public enum Sex { MALE, FEMALE }; private String name; private LocalDate birthday; private Sex gender; private String emailAddress; public int getAge() { /* Calcola e restituisce l'età / } public String getPerson() { / Restituisce una rappresentazione testuale del membro */ } } Soluzione 1: Metodo statico per selezionare membri con età minima Questo approccio implementa un metodo statico che seleziona i membri con un'età maggiore o uguale a un valore specificato. Esempio: public static String getPersonsOlderThan(ArrayList roster, int age) { String selection = ""; for (Person p : roster) { if (p.getAge() >= age) { selection += p.getPerson() + '\n'; } } return selection; }

Metodo generico: public static String getPersons(ArrayList roster, CheckPerson tester) { String selection = ""; for (Person p : roster) { if (tester.test(p)) { selection += p.getPerson() + '\n' } return selection; } Ora è possibile implementare criteri specifici creando classi che implementano l'interfaccia CheckPerson. Implementazione di un criterio specifico Ad esempio, selezionare membri di genere femminile tra i 18 e i 25 anni: public class CheckPersonEligibleForSelectiveService implements CheckPerson { public boolean test(Person p) { return p.gender == Person.Sex.FEMALE && p.getAge() >= 18 && p.getAge() <= 25; } } Nota : Se il criterio non è riutilizzabile altrove, questa classe potrebbe essere implementata come classe interna. Soluzione 4: Uso di classi anonime Se un criterio è specifico e utilizzato solo in un punto, si può evitare di definire una classe separata usando una classe anonima. Esempio: getPersons(roster, new CheckPerson() { public boolean test(Person p) {

return p.getGender() == Person.Sex.FEMALE && p.getAge() >= 18 && p.getAge() <= 25; } }); Nota : Una classe anonima è una classe interna e segue le stesse regole di scoping. Soluzione 5: Uso di espressioni lambda Con Java 8, è possibile utilizzare espressioni lambda per implementare interfacce funzionali come CheckPerson. Esempio: getPersons(roster, p -> p.getGender() == Person.Sex.FEMALE && p.getAge() >= 18 && p.getAge() <= 25); Sintassi delle espressioni lambda Una lambda è composta da:

  1. Lista di parametri : può essere vuota () o contenere uno o più parametri.
  2. Corpo : può essere una singola istruzione o un blocco di istruzioni racchiuso da {}. Esempi:  Lambda valida: (x, y) -> x + y  Lambda con blocco: (x, y) -> { return x + y; }  Lambda senza parametri: () -> System.out.println("Hello"); Errori comuni :  Mancanza di parentesi per blocchi: (x) -> return x; → ❌  Confusione tra blocco e singola istruzione. Esempio complesso con scoping