Selv om både extends og implements nøgleordet i Java bruges til at implementere Inheritance konceptet i objektorienteret programmering, er der en subtil forskel mellem dem. Nøgleordet extends bruges primært til at udvide en klasse, dvs. til at oprette en underklasse i Java, mens nøgleordet implements bruges til at implementere en grænseflade i Java. Nøgleordet extends kan også bruges af en grænseflade til at udvide en anden grænseflade. For bedre at forstå forskellen mellem extends og implements skal du også lære og forstå forskellen mellem klasse og interface i Java.
Og selv om begge er en integreret del af applikationsudvikling ved hjælp af den objektorienterede metode, er en grænseflade mere abstrakt end en klasse, og derfor bruges den til at definere API eller kontrakt.
På den anden side giver en klasse den konkrete implementering af grænsefladen, dvs. den faktiske kode, der udfører arbejdet. Selv om en klasse også kan være abstrakt til at definere en kontrakt, er det job, der bedst udføres af en grænseflade i Java. Selv Joshua Bloch har i Effective Java anbefalet at bruge interfaces til at deklarere type i Java, da det fremmer flere arvegange i Java, hvilket er begrænset i forhold til C++.
Selv efter Java 8 er kun flere arvegange af type og adfærd understøttet i Java (ved at indføre standardmetoder i Java 8), men flere arvegange af tilstanden understøttes stadig ikke. Hvis du vil vide mere om, hvorfor multiple inheritances ikke understøttes i Java, kan du se her.
Og, Hvis du er ny i Java-verdenen, så anbefaler jeg også, at du gennemgår The Complete Java MasterClass på Udemy for at lære Java på en bedre og mere struktureret måde. Dette er et af de bedste og mest opdaterede kurser til at lære Java online.

Hvad er betydningen af at udvide en klasse

En klasse i Java kan udvide en anden klasse for at blive en underklasse. Når klasse B udvider klasse A, bliver B underklasse (barn) og A bliver overklasse (overordnet klasse). En underklasse kan genbruge alle funktionerne i forældreklassen, og genbrug af kode er en vigtig grund til at udvide en klasse, men kun få forstår, at vigtigere er det definerende forhold, som senere udnyttes af polymorfisme.
For eksempel, hvis klasse B udvider klasse A, kan en referencevariabel af typen A indeholde objektet af B, hvilket betyder, at A nu er blevet polymorf, fordi den kan indeholde både A og B. Dette giver anledning til en teknik til at skabe fleksibel software, kendt som programmering til grænseflade frem for implementering, hvor man altid bruger variabler i den overordnede klasse eller grænseflade til at definere kernealgoritmen.

Fordelen ved at gøre dette er, at enhver ny klasse, der udvider den overordnede klasse, vil have adgang til denne algoritme.
Her er et eksempel på udvidelse af en klasse i 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(); // muligt, fordi B extends A a.show(); // dette vil nu kalde til show() metoden i klasse B }}}Outputbetter show

Du kan se, at ved at udvide klasse A har B nu adgang til show() metoden, den kan endda overskrive adfærden af show() metoden, hvilket er kendt som method overriding i Java. Denne enorme magt kommer ved at bruge nøgleordet extends.
Du kan også læse Head First Design Pattern in Java for at lære mere om teknikken med at programmere til grænseflade frem for implementering. Bogen er også for nylig opdateret til at dække Java SE 8.

Hvad er betydningen af at implementere en grænseflade

Betydningen af at implementere en grænseflade er ikke meget anderledes end at udvide en klasse, men det kommer med en ekstra advarsel. Når en klasse implementerer en grænseflade, skal den levere en implementering af alle metoder, der er erklæret inden for grænsefladen. Hvis den ikke ønsker at levere alle implementeringer, kan den erklære sig selv som en abstrakt klasse.
Hvis den ikke følger disse regler, betyder det, at dit program ikke kan kompileres. Der er mange eksempler på at implementere en grænseflade i Java-kode, men jeg tror, at implementering af Runnable er det mest populære. Dette bruges til at oprette en Runnable-opgave, som kan udføres af en tråd.

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

En instans af R kan nu videregives til enhver metode, der forventer en Runnable, ligesom du kan videregive denne til både execute() og submit() metoden i ExecutorService-klassen for at køre den pågældende opgave i en trådpulje. Da vores klasse har implementeret run()-metoden, den eneste metode fra grænsefladen Runnable, er det en konkret klasse. Hvis den ikke havde implementeret run()-metoden, skal du gøre den abstrakt ved at tilføje nøgleordet abstrakt foran class, f.eks.

abstrakt klasse R implementerer Runnable{}

Vigtige punkter

Her er nogle af de vigtige punkter i forbindelse med extends og implementerer nøgleordet i Java:
1) En klasse kan kun udvide en anden klasse i Java, brug af extends nøgleordet med grænsefladen vil resultere i en kompileringsfejl som vist nedenfor:

interface I{}klasse A{}klasse B udvider A{}klasse C udvider I{}

Når du kompilerer denne kildefil, vil du få følgende fejl:

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

2) En klasse kan kun udvide én klasse, hvis man forsøger at udvide mere end en klasse, vil det igen resultere i en kompileringsfejl som vist nedenfor:

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

3) En grænseflade kan bruge extends nøgleordet til at oprette undergrænseflader i Java e.g. følgende er helt lovligt i Java

interface J extends I{}

4) En grænseflade kan endda udvide flere grænseflader ved at bruge extends nøgleordet som vist nedenfor:

interface k extends I, J{}

5) En klasse kan bruge implements nøgleordet til at implementere en eller flere grænseflader i Java som vist nedenfor:

class D implements I, J, K{}

6) En klasse kan også bruge både extends- og implements-nøgleordet sammen for at udvide en klasse og implementere en grænseflade, det er ret almindeligt i Java som vist i følgende eksempel:

class E extends A implements I, J{}

Når en klasse gør det, er den nu en underklasse af A og en subinterface af I og J, hvilket betyder, at du kan bruge en referencevariabel af klasse E og interface I, J til at gemme objektet klasse E som vist nedenfor:

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

Dette giver klasse E enorme muligheder for at bruge arvelighed og polymorfisme.
7) Sidst men ikke mindst kan en grænseflade ikke bruge implements-nøgleordet til at implementere en grænseflade, det er ulovligt i Java, og compileren vil kaste en fejl som vist nedenfor:

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

Det er alt om forskellen mellem extends- og implements-nøgleordet i Java. Det er klart, at extends generelt bruges til at udvide en klasse, og at implements generelt bruges til at implementere en grænseflade. Selv om der er flere finesser, f.eks. kan en grænseflade også udvide en anden grænseflade for at blive en undergrænseflade, en klasse kan også være abstrakt, selv efter at have implementeret en grænseflade, men det, der ikke ændrer sig, er, at de begge bruges til at skabe forældre-barn-forholdet i Java.
Hvis klasse B udvider en anden klasse A, bliver den dens børn, og klasse A bliver en forælder. Det samme er tilfældet med grænsefladen. Du kan yderligere læse Head First Java og Head First Object-Oriented Analysis for at lære mere om de grundlæggende byggesten i objektorienteret programmering i java.
Andre Java-interviewspørgsmål, du måske kan lide

  • Skellen mellem Aggregation, Association og Composition i Java? (svar)
  • Den forskel mellem abstrakt klasse og grænseflade i Java? (svar)
  • Skellen mellem arvelighed og polymorfisme i Java? (svar)
  • Skellen mellem abstraktion og polymorfisme i Java? (svar)
  • Hvorfor er komposition bedre end arvelighed i Java? (artikel)
  • Skellen mellem statiske og ikke-statiske variabler i Java? (svar)
  • Hvorfor er abstrakte klasser vigtige i Java? (udtalelse)

Videre læring
Complete Java Masterclass
Java Fundamentals: Java-sproget
Java i dybden: Bliv en komplet Java-ingeniør!

Skriv et svar

Din e-mailadresse vil ikke blive publiceret.