Interfacce Java

1. Panoramica

In questo tutorial parleremo delle interfacce in Java. Vedremo anche come Java li utilizza per implementare il polimorfismo e le eredità multiple.

2. Cosa sono le interfacce in Java?

In Java, un'interfaccia è un tipo astratto che contiene una raccolta di metodi e variabili costanti. È uno dei concetti fondamentali in Java e viene utilizzato per ottenere astrazione, polimorfismo ed eredità multiple .

Vediamo un semplice esempio di un'interfaccia in Java:

public interface Electronic { // Constant variable String LED = "LED"; // Abstract method int getElectricityUse(); // Static method static boolean isEnergyEfficient(String electtronicType) { if (electtronicType.equals(LED)) { return true; } return false; } //Default method default void printDescription() { System.out.println("Electronic Description"); } } 

Possiamo implementare un'interfaccia in una classe Java utilizzando la parola chiave implements .

Successivamente, creiamo anche una classe Computer che implementa l' interfaccia elettronica che abbiamo appena creato:

public class Computer implements Electronic { @Override public int getElectricityUse() { return 1000; } } 

2.1. Regole per la creazione di interfacce

In un'interfaccia, siamo autorizzati a utilizzare:

  • variabili costanti
  • metodi astratti
  • metodi statici
  • metodi predefiniti

Dobbiamo anche ricordare che:

  • non possiamo istanziare le interfacce direttamente
  • un'interfaccia può essere vuota, senza metodi o variabili in essa
  • non possiamo usare l' ultima parola nella definizione dell'interfaccia, poiché risulterà in un errore del compilatore
  • tutte le dichiarazioni di interfaccia dovrebbero avere il modificatore di accesso pubblico o predefinito; il modificatore astratto verrà aggiunto automaticamente dal compilatore
  • un metodo di interfaccia non può essere privato , protetto o definitivo
  • le variabili di interfaccia sono pubbliche , statiche e finali per definizione; non siamo autorizzati a modificare la loro visibilità

3. Cosa possiamo ottenere usandoli?

3.1. Funzionalità comportamentale

Utilizziamo interfacce per aggiungere determinate funzionalità comportamentali che possono essere utilizzate da classi non correlate. Ad esempio, Comparable , Comparator e Cloneable sono interfacce Java che possono essere implementate da classi non correlate. Qui di seguito è un esempio del comparatore dell'interfacciache viene utilizzato per confrontare due istanze della classe Employee :

public class Employee { private double salary; public double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } } public class EmployeeSalaryComparator implements Comparator { @Override public int compare(Employee employeeA, Employee employeeB) { if (employeeA.getSalary()  employeeB.getSalary()) { return 1; } else { return 0; } } } 

Per ulteriori informazioni, visita il nostro tutorial su Comparator e Comparable in Java.

3.2. Eredità multiple

Le classi Java supportano l'ereditarietà singolare. Tuttavia, utilizzando le interfacce, siamo anche in grado di implementare più eredità.

Ad esempio, nell'esempio seguente, notiamo che la classe Carimplementa le interfacce Fly e Transform . In questo modo eredita i metodi fly and transform :

public interface Transform { void transform(); } public interface Fly { void fly(); } public class Car implements Fly, Transform { @Override public void fly() { System.out.println("I can Fly!!"); } @Override public void transform() { System.out.println("I can Transform!!"); } } 

3.3. Polimorfismo

Cominciamo con la domanda: cos'è il polimorfismo? È la capacità di un oggetto di assumere forme diverse durante il runtime. Per essere più specifici, è l'esecuzione del metodo override correlato a un tipo di oggetto specifico in fase di esecuzione.

In Java, possiamo ottenere il polimorfismo utilizzando le interfacce. Ad esempio, l' interfaccia Shape può assumere forme diverse: può essere un cerchio o un quadrato.

Cominciamo definendo l' interfaccia Shape :

public interface Shape { String name(); } 

Ora creiamo anche la classe Circle :

public class Circle implements Shape { @Override public String name() { return "Circle"; } } 

E anche la classe Square :

public class Square implements Shape { @Override public String name() { return "Square"; } } 

Infine, è il momento di vedere il polimorfismo in azione usando la nostra interfaccia Shape e le sue implementazioni. Diamo istanziare alcuni Forma oggetti, aggiungerli ad una lista , e, infine, stampare i loro nomi in un ciclo:

List shapes = new ArrayList(); Shape circleShape = new Circle(); Shape squareShape = new Square(); shapes.add(circleShape); shapes.add(squareShape); for (Shape shape : shapes) { System.out.println(shape.name()); } 

4. Metodi predefiniti nelle interfacce

Le interfacce tradizionali in Java 7 e versioni precedenti non offrono compatibilità con le versioni precedenti.

Ciò significa che se si dispone di codice legacy scritto in Java 7 o versioni precedenti e si decide di aggiungere un metodo astratto a un'interfaccia esistente, tutte le classi che implementano tale interfaccia devono sovrascrivere il nuovo metodo astratto . In caso contrario, il codice si interromperà.

Java 8 ha risolto questo problema introducendo il metodo predefinito che è opzionale e può essere implementato a livello di interfaccia.

5. Regole di ereditarietà dell'interfaccia

Per ottenere più eredità tramite le interfacce, dobbiamo ricordare alcune regole. Esaminiamoli in dettaglio.

5.1. Interfaccia che estende un'altra interfaccia

When an interface extends another interface, it inherits all of that interface's abstract methods. Let's start by creating two interfaces, HasColor and Shape:

public interface HasColor { String getColor(); } public interface Box extends HasColor { int getHeight() } 

In the example above, Box inherits from HasColor using the keyword extends. By doing so, the Box interface inherits getColor. As a result, the Box interface now has two methods: getColor and getHeight.

5.2. Abstract Class Implementing an Interface

When an abstract class implements an interface, it inherits all of its abstract and default methods. Let's consider the Transform interface and the abstract class Vehicle that implements it:

public interface Transform { void transform(); default void printSpecs(){ System.out.println("Transform Specification"); } } public abstract class Vehicle implements Transform {} 

In this example, the Vehicle class inherits two methods: the abstract transform method and the default printSpecs method.

6. Functional Interfaces

Java has had many functional interfaces since its early days, such as Comparable (since Java 1.2) and Runnable (since Java 1.0).

Java 8 ha introdotto nuove interfacce funzionali come Predicate , Consumer e Function . Per saperne di più su questi, visita il nostro tutorial sulle interfacce funzionali in Java 8.

7. Conclusione

In questo tutorial, abbiamo fornito una panoramica delle interfacce Java e abbiamo parlato di come usarle per ottenere polimorfismo ed eredità multiple.

Come sempre, gli esempi di codice completi sono disponibili su GitHub.