Interfacce e Metodi Privati in Java

Concetti Chiave
  • Le interfacce in Java possono contenere metodi privati, che possono essere utilizzati da metodi predefiniti all'interno dell'interfaccia stessa.
  • I metodi privati in un'interfaccia non sono visibili al di fuori dell'interfaccia e non possono essere ereditati dalle classi che implementano l'interfaccia.
  • I metodi privati dell'interfaccia possono essere utilizzati per evitare la duplicazione del codice tra i metodi predefiniti.

Metodi private nelle Interfacce

A partire da JDK 9, un'interfaccia può includere un metodo privato.

Un metodo privato dell'interfaccia può essere chiamato solo da un metodo predefinito o da un altro metodo privato definito dalla stessa interfaccia.

Poiché un metodo privato dell'interfaccia è specificato come private, non può essere utilizzato da codice esterno all'interfaccia in cui è definito. Questa restrizione include le sottointerfacce perché un metodo privato dell'interfaccia non è ereditato da una sottointerfaccia.

Il vantaggio principale di un metodo privato dell'interfaccia è che consente a due o più metodi predefiniti di utilizzare un pezzo comune di codice, evitando così la duplicazione del codice.

Ad esempio, ecco un'altra versione dell'interfaccia StackInteri che ha due metodi predefiniti chiamati prelevaNElementi() e saltaEPrelevaNElementi(). Il primo restituisce un array che contiene i primi N elementi sulla pila. Il secondo salta un numero specificato di elementi e poi restituisce un array che contiene i successivi N elementi. Entrambi usano un metodo privato chiamato ottieniElementi() per ottenere un array degli elementi specificati dalla pila.

// Un'altra versione di StackInteri che ha un metodo privato
// dell'interfaccia che è utilizzato da due metodi predefiniti.
interface StackInteri {
    void push(int elemento); // memorizza un elemento
    int pop(); // recupera un elemento

    // Un metodo predefinito che restituisce un array contenente
    // i primi n elementi della pila.
    default int[] prelevaNElementi(int n) {
        // Restituisce gli elementi richiesti.
        return ottieniElementi(n);
    }

    // Un metodo predefinito che restituisce un array contenente
    // i successivi n elementi sulla pila dopo aver saltato degli elementi.
    default int[] saltaEPrelevaNElementi(int salta, int n) {

        // Salta il numero specificato di elementi.
        ottieniElementi(salta);

        // Restituisce gli elementi richiesti.
        return ottieniElementi(n);
    }

    // Un metodo privato che restituisce un array contenente
    // i primi n elementi sulla pila
    private int[] ottieniElementi(int n) {
        int[] elementi = new int[n];

        for(int i = 0; i < n; i++) elementi[i] = preleva();
        return elementi;
    }
}
Consiglio

Uso condiviso del metodo privato

Si noti che sia prelevaNElementi() che saltaEPrelevaNElementi() utilizzano il metodo privato ottieniElementi() per ottenere l'array da restituire.

Questo impedisce che entrambi i metodi debbano duplicare la stessa sequenza di codice.

Si tenga presente che poiché ottieniElementi() è privato, non può essere chiamato da codice al di fuori di StackInteri.

Pertanto, il suo utilizzo è limitato ai metodi predefiniti all'interno di StackInteri.

Inoltre, poiché ottieniElementi() utilizza il metodo pop() per ottenere gli elementi dalla pila, chiamerà automaticamente l'implementazione di pop() fornita dall'implementazione di StackInteri. Pertanto, ottieniElementi() funzionerà con qualsiasi pila che implementi StackInteri.

L'utilizzo di metodi privati nelle interfacce è una di quelle funzionalità che vengono adoperate raramente dal momento che sono utilizzate esclusivamente dai metodi di default. In ogni caso, è una funzionalità utile da conoscere.