Anche se entrambe le parole chiave extends e implements in Java sono usate per implementare il concetto di ereditarietà della programmazione orientata agli oggetti, c’è una sottile differenza tra loro. La parola chiave extends è usata principalmente per estendere una classe, cioè per creare una sottoclasse in Java, mentre la parola chiave implements è usata per implementare un’interfaccia in Java. La parola chiave extends può anche essere usata da un’interfaccia per estendere un’altra interfaccia. Per capire meglio la differenza tra estende e implementa, dovete anche imparare e capire la differenza tra classe e interfaccia in Java.
Anche se entrambe sono parte integrante dello sviluppo di un’applicazione usando la metodologia orientata agli oggetti, un’interfaccia è più astratta di una classe e quindi viene usata per definire l’API o il contratto.
D’altra parte, una classe fornisce l’implementazione concreta dell’interfaccia, cioè il codice effettivo che fa il lavoro. Sebbene una classe possa anche essere astratta per definire un contratto, è il lavoro meglio svolto da un’interfaccia in Java. Anche Joshua Bloch ha consigliato in Effective Java di usare le interfacce per dichiarare il tipo in Java, in quanto promuove le eredità multiple in Java, che sono limitate rispetto al C++.
Anche dopo Java 8, solo le eredità multiple di tipo e comportamento sono supportate in Java (introducendo metodi predefiniti in Java 8), ma le eredità multiple dello stato non sono ancora supportate. Se vuoi saperne di più sul perché le eredità multiple non sono supportate in Java, vedi qui.
E, se sei nuovo nel mondo Java allora ti consiglio anche di passare attraverso The Complete Java MasterClass su Udemy per imparare Java in un modo migliore e più strutturato. Questo è uno dei migliori e aggiornati corsi per imparare Java online.

Che cosa significa estendere una classe

Una classe in Java può estendere un’altra classe per diventare una sottoclasse. Quando la classe B estende la classe A, B diventa sottoclasse (figlio) e A diventa superclasse (genitore). Una sottoclasse può riutilizzare tutte le caratteristiche della classe madre e il riutilizzo del codice è la ragione principale per estendere una classe, ma pochi capiscono che più importante è la relazione di definizione che viene poi sfruttata dal polimorfismo.
Per esempio, se la classe B estende la classe A allora una variabile di riferimento di tipo A può contenere l’oggetto di B, il che significa che A ora diventa polimorfo perché può contenere sia A che B. Questo dà vita ad una tecnica di creazione di software flessibile, conosciuta come programmazione per interfaccia che per implementazione dove si usano sempre le variabili della classe madre o dell’interfaccia per definire l’algoritmo di base.

Il vantaggio di fare questo è che ogni nuova classe che estende la classe madre avrà accesso a quell’algoritmo.
Ecco un esempio di estensione di una classe in Java:

class A { public void show() { System.out.println("show"); }}class B extends A { public void display() { System.out.println("display"); } public void show() { System.out.println("better show"); }}public class Main { public static void main(String args) { A a = new B(); // possibile perché B estende A a.show(); // questo ora chiamerà il metodo show() della classe B }}Outputbetter show

Si può vedere che estendendo la classe A, B ora ha accesso al metodo show(), può anche sovrascrivere il comportamento del metodo show(), che è conosciuto come metodo di override in Java. Questo immenso potere deriva dall’uso della parola chiave extends.
Puoi anche leggere Head First Design Pattern in Java per imparare di più sulla tecnica di programmazione per interfaccia che per implementazione. Il libro è stato recentemente aggiornato per coprire Java SE 8.

Qual è il significato di implementare un’interfaccia

Il significato di implementare un’interfaccia non è molto diverso da quello di estendere una classe, ma viene con un avvertimento aggiuntivo. Quando una classe implementa un’interfaccia deve fornire un’implementazione di tutti i metodi dichiarati nell’interfaccia. Se non vuole fornire tutte le implementazioni, può dichiararsi come una classe astratta.
Non seguire queste regole significa che il vostro programma non può essere compilato. Ci sono molti esempi di implementazione di un’interfaccia nel codice Java, ma credo che l’implementazione di Runnable sia la più popolare. Questo è usato per creare un task Runnable che può essere eseguito da un thread.

class R implements Runnable{public void run(){ System.out.println("do nothing"); }}

Un’istanza di R ora può essere passata a qualsiasi metodo che si aspetta un Runnable come si può passare a entrambi i metodi execute() e submit() della classe ExecutorService per eseguire quel task in un thread pool. Poiché la nostra classe ha implementato il metodo run(), il singolo metodo dell’interfaccia Runnable, è una classe concreta. Se non avesse implementato il metodo run() dovrete renderla astratta aggiungendo la parola chiave abstract davanti a class, per esempio

la classe astratta R implementa Runnable{}

Punti importanti

Questi sono alcuni dei punti importanti relativi alle parole chiave extends e implements in Java:
1) Una classe può solo estendere un’altra classe in Java, l’uso della parola chiave extends con l’interfaccia risulterà in un errore di compilazione come mostrato di seguito:

interfaccia I{}class A{}class B extends A{}class C extends I{}

Quando si compila questo file sorgente si ottiene il seguente errore:

$ javac Main.javaMain.java:27: no interface expected hereclass C extends I{^1 error

2) Una classe può estendere solo una classe, cercando di estendere più di una classe si otterrà nuovamente un errore di compilazione come mostrato di seguito:

class C extends A, B{}$ javac Main.javaMain.java:27: '{' expectedclass C extends A, B{^1 error

3) Un’interfaccia può usare extends keyword per creare sottointerfacce in Java e.g. Il seguente è perfettamente legale in Java

interfaccia J estende I{}

4) Un’interfaccia può anche estendere più interfacce usando la parola chiave extends come mostrato sotto:

interfaccia k estende I, J{}

5) Una classe può usare la parola chiave implements per implementare una o più interfacce in Java come mostrato sotto:

classe D implementa I, J, K{}

6) Una classe può anche usare entrambe le parole chiave extends e implements insieme per estendere una classe e implementare un’interfaccia, è abbastanza comune in Java come mostrato nel seguente esempio:

classe E estende A implementa I, J{}

Quando una classe fa questo è ora una sottoclasse di A e una sottointerfaccia di I e J, il che significa che si può usare una variabile di riferimento della classe E e dell’interfaccia I, J per memorizzare l’oggetto della classe E come mostrato di seguito:

I i = nuovo E();J j = nuovo E();A a = nuovo E();

Questo dà un immenso potere alla classe E in termini di utilizzo di Ereditarietà e Polimorfismo.
7) Ultimo ma non meno importante, un’interfaccia non può usare la parola chiave implements per implementare un’interfaccia, è illegale in Java e il compilatore darà un errore come mostrato sotto:

interfaccia L implements J{}javac Main.javaMain.java:49: '{' expectedinterface L implements J{^1 error

Questo è tutto sulla differenza tra extends e implements keyword in Java. È chiaro che extends è generalmente usato per estendere una classe e implements è generalmente usato per implementare un’interfaccia. Anche se ci sono più sottigliezze, ad esempio un’interfaccia può anche estendere un’altra interfaccia per diventare una sottointerfaccia, una classe può anche essere astratta anche dopo aver implementato un’interfaccia, ma ciò che non cambia è che entrambi sono usati per creare la relazione genitore-figlio in Java.
Se la classe B estende un’altra classe A diventa la sua figlia e la classe A diventa un genitore. Lo stesso vale per l’interfaccia. Puoi anche leggere Head First Java e Head First Object-Oriented Analysis per saperne di più sugli elementi di base della programmazione orientata agli oggetti in Java.
Altre domande di intervista su Java che potrebbero piacerti

  • La differenza tra aggregazione, associazione e composizione in Java? (risposta)
  • La differenza tra classe astratta e interfaccia in Java? (risposta)
  • La differenza tra Ereditarietà e Polimorfismo in Java? (risposta)
  • La differenza tra Astrazione e Polimorfismo in Java? (risposta)
  • Perché la composizione è meglio dell’ereditarietà in Java? (articolo)
  • La differenza tra le variabili statiche e non statiche in Java? (risposta)
  • Perché la classe astratta è importante in Java? (opinione)

Altro apprendimento
Completa Java Masterclass
Fondamenti di Java: Il linguaggio Java
Java in profondità: Diventa un ingegnere Java completo!

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.