Index

Related

TLDR

Un’interfaccia specifica un insieme di metodi che una classe deve implementare se vuole implementare quell’interfaccia


Introduzione

In Java, un’interfaccia è un tipo di riferimento che può contenere solo:

  • Metodi astratti
  • Campi costanti (che sono implicitamente public, static, e final

Le interfacce vengono utilizzate per definire un contratto che deve essere implementato da una classe concreta. In altre parole, una classe che implementa un’interfaccia deve fornire una implementazione per tutti i metodi definiti nell’interfaccia.

Esempio

java
public interface FormaGeometrica {
  double PI = 3.14;
  double area();
  double perimetro();
}

Implementazione

Implementare un interfaccia significa creare una classe che implementa i metodi (astratti) contenuti dall’interfaccia

Esempio

public class Cerchio implements FormaGeometrica {
  private double raggio;
  
  public Cerchio(double raggio) {
     this.raggio = raggio;
  }
  
  @Override
  public double area() {
     return PI * raggio * raggio;
  }
  
  @Override
  public double perimetro() {
     return 2 * PI * raggio;
  }
}

In questo esempio, abbiamo definito una classe Cerchio che implementa l’interfaccia FormaGeometrica. La classe Cerchio deve fornire una implementazione per i metodi area() e perimetro() definiti nell’interfaccia.

Metodi Default e Statici

Le interfacce possono anche contenere metodi di default e statici, che possono essere implementati direttamente nell’interfaccia stessa.

Metodi di Default

Definendo metodi con implementazione di default all’interno delle interfacce diamo la libertà a chi implementa l’interfaccia di scegliere se sovrascrivere il metodo di default o utilizzare l’implementazione predefinita.

Metodi Statici

Definendo metodi statici all’interno delle interfacce. Questi metodi possono essere chiamati utilizzando il nome dell’interfaccia seguito dal nome del metodo.

Esempio

public interface FormaGeometrica {
  double PI = 3.14;
  
  default double areaCirconferenza(double raggio) {
     return PI * raggio * raggio;
  }
  
  static double areaQuadrato(double lato) {
     return lato * lato;
  }
  double area();
  double perimetro();
}

Eredità Multipla

Java supporta l’ereditarietà multipla tramite le interfacce. Una classe può implementare più di un’interfaccia, consentendo così di ereditare comportamenti da più fonti.

Tuttavia, Java non supporta direttamente l’ereditarietà multipla per le classi. Ciò significa che una classe in Java può estendere solo una singola classe base. Tuttavia, Java supporta l’ereditarietà multipla indiretta attraverso l’utilizzo di interfacce.


Estendibilità

Le interfacce possono estendere altre interfacce, consentendo la creazione di gerarchie di interfacce. Una classe che implementa un’interfaccia estesa deve fornire implementazioni per tutti i metodi definiti nelle interfacce padre.


Interfacce Funzionali

Le interfacce funzionali sono un tipo speciale di interfacce che hanno un solo metodo astratto, che può essere implementato come una funzione lambda. Queste interfacce sono anche note come interfacce a singolo metodo o SAM (Single Abstract Method) interfaces.

Le interfacce funzionali sono state introdotte per semplificare l’uso delle funzioni lambda in Java, che sono blocchi di codice anonimi che possono essere passati come argomenti a metodi o assegnati a variabili. Le funzioni lambda possono essere utilizzate per creare oggetti che implementano interfacce funzionali, il che può semplificare il codice e renderlo più conciso ed espressivo.