Deși ambele cuvinte cheie extends și implements în Java sunt folosite pentru a implementa conceptul de moștenire din programarea orientată pe obiecte, există o diferență subtilă între ele. Cuvântul cheie extends este utilizat în principal pentru a extinde o clasă, adică pentru a crea o subclasă în Java, în timp ce cuvântul cheie implements este utilizat pentru a implementa o interfață în Java. Cuvântul cheie extends poate fi, de asemenea, utilizat de o interfață pentru a extinde o altă interfață. Pentru a înțelege mai bine diferența dintre extends și implements, trebuie, de asemenea, să învățați și să înțelegeți diferența dintre clasă și interfață în Java.
Deși ambele sunt parte integrantă a dezvoltării aplicațiilor care utilizează metodologia orientată pe obiecte, o interfață este mai abstractă decât clasa, prin urmare este utilizată pentru a defini API sau contract.
Pe de altă parte, o clasă oferă implementarea concretă a interfeței, adică codul real care face treaba. Cu toate că o clasă poate fi, de asemenea, abstractă pentru a defini un contract, este o sarcină pe care o îndeplinește cel mai bine o interfață în Java. Chiar și Joshua Bloch a sfătuit în Effective Java despre utilizarea interfețelor pentru a declara tipul în Java, deoarece promovează moștenirile multiple în Java, ceea ce este restricționat în comparație cu C++.
Inclusiv după Java 8, doar moștenirile multiple ale tipului și comportamentului sunt acceptate în Java (prin introducerea metodelor implicite în Java 8), dar moștenirile multiple ale stării nu sunt încă acceptate. Dacă doriți să aflați mai multe despre motivul pentru care moștenirile multiple nu sunt acceptate în Java, vedeți aici.
Și, Dacă sunteți nou în lumea Java, atunci vă recomand, de asemenea, să parcurgeți The Complete Java MasterClass pe Udemy pentru a învăța Java într-un mod mai bun și mai structurat. Acesta este unul dintre cele mai bune și actualizate cursuri pentru a învăța Java online.
Ce înseamnă extinderea unei clase
O clasă în Java poate extinde o altă clasă pentru a deveni o subclasă. Atunci când clasa B extinde clasa A, B devine subclasă (copil), iar A devine superclasă (părinte). O subclasă poate reutiliza toate caracteristicile clasei părinte, iar reutilizarea codului este un motiv important pentru a extinde o clasă, dar puțini înțeleg că mai importantă este relația de definire, care este ulterior valorificată prin polimorfism.
De exemplu, dacă clasa B extinde clasa A, atunci o variabilă de referință de tip A poate conține obiectul B, ceea ce înseamnă că A devine acum polimorfă, deoarece poate conține atât A, cât și B. Acest lucru dă naștere unei tehnici de creare a unui software flexibil, cunoscută sub numele de programare pentru interfață decât pentru implementare, în care se utilizează întotdeauna variabilele clasei părinte sau ale interfeței pentru a defini algoritmul de bază.
Beneficiul de a face acest lucru este că orice clasă nouă care extinde clasa părinte va avea acces la acel algoritm.
Iată un exemplu de extindere a unei clase în Java:
class A { public void show() { System.out.println("show"); }}class B extends A { public void display() { 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(); // posibil deoarece B extinde A a.show(); // acest lucru va apela acum la metoda show() a clasei B }}Outputbetter show
Vezi că prin extinderea clasei A, B are acum acces la metoda show(), poate chiar să suprascrie comportamentul metodei show(), ceea ce este cunoscut sub numele de suprascriere de metode în Java. Această putere imensă vine prin utilizarea cuvântului cheie extends.
Puteți citi, de asemenea, Head First Design Pattern in Java pentru a afla mai multe despre tehnica de programare pentru interfață decât pentru implementare. Cartea este, de asemenea, recent actualizată pentru a acoperi Java SE 8.
Care este semnificația implementării unei interfețe
Semnificația implementării unei interfețe nu este foarte diferită de extinderea unei clase, dar vine cu un avertisment suplimentar. Atunci când o clasă implementează o interfață, aceasta trebuie să furnizeze o implementare a tuturor metodelor declarate în interiorul interfeței. Dacă nu dorește să furnizeze toate implementările, se poate declara ca fiind o clasă abstractă.
Nerespectarea acestor reguli înseamnă că programul dumneavoastră nu poate fi compilat. Există multe exemple de implementare a unei interfețe în codul Java, dar cred că implementarea Runnable este cea mai populară. Aceasta este utilizată pentru a crea o sarcină Runnable care poate fi executată de un fir de execuție.
class R implements Runnable{public void run(){ System.out.println("do nothing"); }}
O instanță a lui R poate fi transmisă acum oricărei metode care așteaptă un Runnable, cum ar fi, de exemplu, puteți trece aceasta atât la metoda execute(), cât și la metoda submit() a clasei ExecutorService pentru a rula sarcina respectivă într-un grup de fire de execuție. Deoarece clasa noastră a implementat metoda run(), singura metodă din interfața Runnable, aceasta este o clasă concretă. Dacă nu ar fi implementat metoda run(), ar trebui să o faceți abstractă prin adăugarea cuvântului cheie abstract în fața clasei, de exemplu
clasa abstractă R implementează Runnable{}
Puncte importante
Iată câteva dintre punctele importante legate de cuvintele cheie extends și implements în Java:
1) O clasă poate extinde doar o altă clasă în Java, utilizarea cuvântului cheie extends cu interfața va duce la o eroare de compilare, așa cum se arată mai jos:
interfață I{}clasa A{}clasa B extinde A{}clasa C extinde I{}
Când compilați acest fișier sursă, veți obține următoarea eroare:
$ javac Main.javaMain.java.java:27: no interface expected hereclass C extends I{^1 error
2) O clasă poate extinde doar o singură clasă, încercarea de a extinde mai multe clase va duce din nou la o eroare de compilare, așa cum se arată mai jos:
class C extends A, B{}$ javac Main.javaMain.java.java:27: '{' expectedclass C extends A, B{^1 error
3) O interfață poate folosi cuvântul cheie extends pentru a crea subinterfețe în Java e.g. ceea ce urmează este perfect legal în Java
interfața J extends I{}
4) O interfață poate extinde chiar mai multe interfețe prin utilizarea cuvântului cheie extends, așa cum se arată mai jos:
interfața k extends I, J{}
5) O clasă poate utiliza cuvântul cheie implements pentru a implementa una sau mai multe interfețe în Java, așa cum se arată mai jos:
clasa D implementează I, J, K{}
6) O clasă poate folosi, de asemenea, atât cuvântul cheie extends cât și implements împreună pentru a extinde o clasă și a implementa o interfață, este destul de comun în Java, așa cum se arată în următorul exemplu:
clasa E extends A implementează I, J{}
Când o clasă face acest lucru, ea este acum o subclasă a lui A și o subinterfață a lui I și J, ceea ce înseamnă că se poate utiliza o variabilă de referință a clasei E și a interfeței I, J pentru a stoca obiectul clasei E, după cum se arată mai jos:
I i = new E();J j = new E();A a = new E();
Acest lucru conferă clasei E o putere imensă în ceea ce privește utilizarea moștenirii și polimorfismului.
7) Nu în ultimul rând, o interfață nu poate folosi cuvântul cheie implements pentru a implementa o interfață, este ilegal în Java și compilatorul va arunca o eroare, așa cum se arată mai jos:
interfață L implementează J{}javac Main.javaMain.java:49: '{' expectedinterfață L implementează J{^1 eroare
Acesta este tot despre diferența dintre cuvintele cheie extends și implements în Java. Este clar că extends este utilizat în general pentru a extinde o clasă, iar implements este utilizat în general pentru a implementa o interfață. Deși există mai multe subtilități, de exemplu, o interfață poate, de asemenea, să extindă o altă interfață pentru a deveni o subinterfață, o clasă poate fi, de asemenea, abstractă chiar și după ce implementează o interfață, dar ceea ce nu se schimbă este faptul că ambele sunt utilizate pentru a crea relația părinte-copil în Java.
Dacă clasa B extinde o altă clasă A, aceasta devine copilul său, iar clasa A devine părinte. Același lucru este valabil și în cazul interfeței. Puteți citi în continuare Head First Java și Head First Object-Oriented Analysis pentru a afla mai multe despre elementele de bază ale programării orientate pe obiecte în java.
Alte întrebări de interviu Java care v-ar putea plăcea
- Diferența dintre agregare, asociere și compoziție în Java? (răspuns)
- Diferența dintre clasa abstractă și interfața în Java? (răspuns)
- Diferența dintre Ereditate și Polimorfism în Java? (răspuns)
- Diferența dintre Abstracțiere și Polimorfism în Java? (răspuns)
- De ce Composition este mai bună decât Inheritance în Java? (articol)
- Diferența dintre variabilele statice și non-statice în Java? (răspuns)
- De ce este importantă clasa abstractă în Java? (opinie)
Învățare suplimentară
Complet Java Masterclass
Java Fundamentals: Limbajul Java
Java In-Depth: Deveniți un inginer Java complet!