interface enhancements java 8 java functional interface
Tento výukový program vysvetľuje doplnky k rozhraniu v jazyku Java 8 a rozdiely medzi konceptmi Java, ako je abstraktná trieda, rozširuje kľúčové slovo atď., S rozhraniami:
Preskúmali sme všetko okolo Rozhrania v Jave v našom poslednom návode. Zaviedli sme a pokryli základné koncepty rozhraní v Jave vrátane viacerých rozhraní.
Pred jazykom Java 8 mali rozhrania povolené iba abstraktné metódy a statické a konečné premenné. Abstraktné metódy sú predvolene verejné a musí ich prepísať trieda, ktorá implementuje rozhranie.
Rozhranie teda bolo hlavne zmluvou a týkalo sa iba konštantných (statických a konečných) a abstraktných metód.
=> Tu si pozrite príručku Java Beginners Guide.
Čo sa dozviete:
- Zmeny rozhraní v prostredí Java 8
- Funkčné rozhrania Java 8
- Rozhranie triedy Vs v Jave
- Java rozširuje vs implementácie
- Rozhranie Vs Abstraktná trieda v Jave
- Záver
Zmeny rozhraní v prostredí Java 8
Vydanie Java 8 zavádza alebo umožňuje, aby sme v rozhraniach mali statické a predvolené metódy. Pomocou predvolených metód v rozhraní môžu vývojári do rozhraní pridať ďalšie metódy. Týmto spôsobom nenarúšajú ani nemenia triedy, ktoré implementujú rozhranie.
Java 8 tiež umožňuje, aby malo rozhranie statickú metódu. Statické metódy sú rovnaké ako tie, ktoré definujeme v triedach. Všimnite si, že statickú metódu nemôže prepísať trieda, ktorá implementuje rozhranie.
Zavedenie statických a predvolených metód do rozhrania uľahčilo bez problémov zmeny rozhraní a tiež uľahčilo implementáciu rozhraní.
Java 8 taktiež zavádza „Lambda Expressions“ do funkčných rozhraní. Okrem toho od verzie Java 8 je v aplikácii Java pridaných viac zabudovaných funkčných rozhraní.
V tomto výučbe sa budeme zaoberať všetkými týmito doplnkami k rozhraniam v prostredí Java 8 a taktiež s nimi rozoberieme niektoré rozdiely medzi rôznymi konceptmi Java, ako sú abstraktné triedy, kľúčové slovo extends atď.
Statická metóda v rozhraní v Jave
Rozhrania môžu obsahovať aj metódy, ktoré môžu mať definície. Toto sú statické metódy v rozhraní. Statické metódy sú definované vo vnútri rozhrania a nemôžu byť prepísané alebo zmenené triedami, ktoré implementujú toto rozhranie.
Tieto statické metódy môžeme nazvať priamo pomocou názvu rozhrania.
Nasledujúci príklad demonštruje použitie statickej metódy.
//interface declaration interface TestInterface { // static method definition static void static_print() { System.out.println('TestInterface::static_print ()'); } // abstract method declaration void nonStaticMethod(String str); } // Interface implementation class TestClass implements TestInterface { // Override interface method @Override public void nonStaticMethod(String str) { System.out.println(str); } } public class Main{ public static void main(String() args) { TestClass classDemo = new TestClass(); // Call static method from interface TestInterface.static_print(); // Call overridden method using class object classDemo.nonStaticMethod('TestClass::nonStaticMethod ()'); } }
Výkon:
Vyššie uvedený program má TestInterface. Má statickú metódu s názvom „static_print“ a tiež nestatickú metódu s názvom nonstaticmethod.
Implementovali sme TestInterface v TestClass a prepísali nonStaticMethod. Potom v hlavnej metóde zavoláme metódu static_print priamo pomocou TestInterface a nonStaticMethod pomocou objektu TestClass.
Predvolená metóda rozhrania
Ako už bolo spomenuté, rozhrania pred Java 8 povoľovali iba abstraktné metódy. Potom by sme poskytli implementáciu tejto metódy v samostatnej triede. Ak by sme do rozhrania museli pridať novú metódu, musíme v rovnakej triede poskytnúť jej implementačný kód.
Ak by sme teda zmenili rozhranie pridaním metódy, zmenila by sa aj implementačná trieda.
Toto obmedzenie prekonala verzia Java 8, ktorá umožňovala rozhraniam predvolené metódy. Predvolené metódy svojím spôsobom poskytujú spätnú kompatibilitu s existujúcimi rozhraniami a triedu implementácie nemusíme meniť. Predvolené metódy sú tiež známe ako „metóda virtuálneho rozšírenia“ alebo „metódy obrancu“.
Predvolené metódy sa deklarujú pomocou kľúčového slova „default“ v deklarácii. Po vyhlásení nasleduje definícia metódy. Predvolenú metódu môžeme prepísať, pretože je k dispozícii pre triedu, ktorá implementuje rozhranie.
Rovnakým spôsobom ho môžeme vyvolať pomocou objektu triedy implementácie z rozhrania priamo bez jeho prepísania.
interface TestInterface { // abstract method public void cubeNumber(int num); // default method default void print() { System.out.println('TestInterface :: Default method'); } } class TestClass implements TestInterface { // override cubeNumber method public void cubeNumber(int num) { System.out.println('Cube of given number ' + num+ ':' + num*num*num); } } class Main{ public static void main(String args()) { TestClass obj = new TestClass(); obj.cubeNumber(5); // call default method print using class object obj.print(); } }
Výkon:
autentifikácia vyžaduje užívateľské meno a heslo router
Vyššie uvedený program Java demonštruje predvolenú metódu v rozhraní. V hlavnej metóde si všimnite, že predvolenú metódu rozhrania môžeme nazvať pomocou objektu triedy. Je to tak preto, lebo keď trieda implementuje rozhranie, je pre triedu k dispozícii aj predvolená metóda.
Poznámka: Metódu print () sme mohli prepísať aj v triede implementácie. Upozorňujeme, že ak je prepísané, potom sa modifikátor prístupu predvolenej metódy zmení na verejný v implementačnej triede.
Predvolené metódy a viacnásobné dedenie
V prípade viacerých rozhraní môže nastať situácia, keď každé rozhranie bude mať predvolenú metódu s rovnakým prototypom. V takom prípade kompilátor nevie, ktorú metódu má vyvolať.
Keď nastane táto situácia, v ktorej má predvolená metóda rovnaký prototyp na všetkých rozhraniach, riešením je prepísať túto metódu v implementačnej triede tak, aby keď objekt triedy implementácie zavolá predvolenú metódu, kompilátor vyvolá metódu implementovanú v triede .
Nasledujúci program Java demonštruje použitie predvolenej metódy s viacerými rozhraniami.
//Interface_One interface Interface_One{ //defaultMethod default void defaultMethod(){ System.out.println('Interface_One::defaultMethod'); } } //Interface_Two interface Interface_Two{ //defaultMethod default void defaultMethod(){ System.out.println('Interface_Two::defaultMethod'); } } class TestExample implements Interface_One, Interface_Two{ public void disp(String str){ System.out.println('String is: '+str); } //override defaultMethod to take care of the ambiguity public void defaultMethod(){ System.out.println('TestExample::defaultMethod'); } } class Main{ public static void main(String() args) { TestExample obj = new TestExample(); //call the default method obj.defaultMethod(); } }
Výkon:
Vo vyššie uvedenom programe sme v implementačnej triede prepísali predvolenú metódu (ktorá má v obidvoch rozhraniach rovnaký prototyp). Týmto spôsobom, keď voláme predvolenú metódu z hlavnej metódy pomocou objektu implementačnej triedy, je vyvolaná prepísaná metóda.
Funkčné rozhrania Java 8
Funkčné rozhranie je rozhranie, ktoré má iba jednu abstraktnú metódu. Môže obsahovať ľubovoľný počet predvolených a statických metód, ale abstraktná metóda, ktorú obsahuje, je presne jedna. Funkčné rozhranie môže mať navyše deklarácie metód triedy objektov.
Funkčné rozhranie je známe ako „ Rozhranie jednej abstraktnej metódy “Alebo„ Rozhranie SAM “. Rozhranie SAM je nová funkcia v Jave.
V programe Java je prítomnosť funkčného rozhrania indikovaná pomocou a @Funkčné rozhranie anotácia. Keď kompilátor narazí na túto anotáciu, vie, že rozhranie, ktoré nasleduje po tejto anotácii, je funkčné. Ak teda obsahuje viac ako jednu abstraktnú metódu, bliká chyba.
Anotácia @Funkčné rozhranie v jazyku Java to však nie je povinné.
Nasledujúci program demonštruje funkčné rozhranie v prostredí Java:
//declare a functional interface @FunctionalInterface //annotation indicates it’s a functional interface interface function_Interface{ void disp_msg(String msg); // abstract method // Object class methods. int hashCode(); String toString(); boolean equals(Object obj); } //implementation of Functional Interface class FunctionalInterfaceExample implements function_Interface{ public void disp_msg(String msg){ System.out.println(msg); } } class Main{ public static void main(String() args) { //create object of implementation class and call method FunctionalInterfaceExample finte = new FunctionalInterfaceExample(); finte.disp_msg('Hello, World!!!'); } }
Výkon:
Funkčné rozhranie vo vyššie uvedenom programe má jednu abstraktnú metódu a tiež obsahuje deklaráciu metódy triedy objektov, ako je hashCode, toString a equals. V triede, ktorá implementuje toto rozhranie, je prepísaná abstraktná metóda. V hlavnej metóde vytvoríme objekt implementačnej triedy a použijeme metódu.
Rozhrania ako Runnable a Comparable sú príkladmi funkčných rozhraní poskytovaných v prostredí Java. Java 8 nám umožňuje priradiť výrazy lambda k objektu funkčného rozhrania.
Nasledujúci príklad programu to demonštruje.
class Main{ public static void main(String args()) { // use lambda expression to create the object new Thread(()-> {System.out.println('New thread created with functional interface');}).start(); } }
Výkon:
Java 8 tiež poskytuje veľa zabudovaných funkčných rozhraní v balíku java.util.function.
Tieto zabudované rozhrania sú popísané nižšie:
# 1) Predikát
Toto je funkčné rozhranie v Jave, ktoré má jediný test abstraktnej metódy. Metóda ‘test’ vráti boolovskú hodnotu po vyskúšaní zadaného argumentu.
Ďalej je uvedený prototyp testovacej metódy rozhrania Predicate.
public interface Predicate { public boolean test(T t); }
# 2) BinaryOperator
Rozhranie BinaryOperator poskytuje abstraktnú metódu „apply“, ktorá prijíma dva argumenty a vracia výslednú hodnotu rovnakého typu ako argumenty.
c ++ náhodne medzi 0 a 1
Prototypom metódy prijatia je:
public interface BinaryOperator { public T apply (T x, T y); }
# 3) Funkcia
Funkčné rozhranie je funkčné rozhranie, ktoré má tiež abstraktnú metódu s názvom „použiť“. Táto použiteľná metóda však berie jediný argument typu T a vracia hodnotu typu R.
Prototyp použitej metódy je nasledovný:
public interface Function { public R apply(T t); }
Nasledujúci program Java demonštruje vyššie zabudovaný predikát funkčného rozhrania.
import java.util.*; import java.util.function.Predicate; class Main { public static void main(String args()) { // create a list of strings List names = Arrays.asList('Karen','Mia','Sydney','Lacey','Megan'); // declare string type predicate and use lambda expression to create object Predicate p = (s)->s.startsWith('M'); System.out.println('Names starting with M:'); // Iterate through the list for (String st:names) { // test each entry with predicate if (p.test(st)) System.out.println(st); } } }
Výkon:
Ako vidíme vo vyššie uvedenom programe, máme zoznam reťazcov. Pomocou funkčného rozhrania Predicate otestujeme, či sa položka v reťazci začína písmenom M a ak áno, potom vypíše názov.
Rozhranie triedy Vs v Jave
Aj keď sú trieda a rozhranie podobné, pretože majú podobnú syntax, tieto dve entity majú viac rozdielov ako podobností.
Uveďme zoznam niektorých rozdielov medzi triedou a rozhraním v Jave.
Trieda | Rozhranie |
---|---|
Môžeme vytvárať inštancie a vytvárať objekty z triedy. | Rozhranie nemožno vytvoriť. |
Kľúčové slovo „trieda“ sa používa na vytvorenie triedy. | Rozhranie sa vytvára pomocou kľúčového slova „interface“. |
Triedy nepodporujú viacnásobné dedenie v Jave. | Rozhrania podporujú viacnásobné dedenie v Jave. |
Trieda obsahuje konštruktory. | Rozhrania neobsahujú konštruktory. |
Trieda nemôže obsahovať abstraktné metódy. | Rozhrania obsahujú iba abstraktné metódy. |
Trieda môže mať premenné a metódy, ktoré sú predvolené, verejné, súkromné alebo chránené. | Rozhranie má v predvolenom nastavení iba verejné premenné a metódy. |
Priraďovať neprístupné modifikátory k premenným triedy nie je povinné. | Rozhrania môžu obsahovať premenné, ktoré sú statické alebo konečné. |
Z triedy môžeme dediť inú triedu. | Triedu nemôžeme zdediť z rozhrania. |
Triedu možno dediť pomocou kľúčového slova „extends“. | Rozhranie môže byť implementované inou triedou pomocou kľúčového slova „implements“. Dá sa dediť iným rozhraním pomocou kľúčového slova „extends“. |
Java rozširuje vs implementácie
„Rozširuje“ | „Vykonáva“ |
---|---|
Rozhrania podporujú iba statické a konečné modifikátory neprístupu. | Abstrakt podporuje všetky neprístupné modifikátory, ako sú statické, konečné, nestatické a nekoncové. |
Trieda používa na dedenie z inej triedy kľúčové slovo „extends“. | Kľúčové slovo „implementuje“ používa trieda na implementáciu rozhrania. |
Trieda dediaca inú triedu môže alebo nemusí prepísať všetky metódy nadradenej triedy. | Trieda implementujúca rozhranie musí prepísať všetky abstraktné metódy rozhrania. |
Pomocou kľúčového slova extends môžeme rozšíriť naraz iba jednu triedu. | Pomocou kľúčového slova „implements“ môžeme implementovať viac rozhraní. |
Rozhranie môže rozšíriť ďalšie rozhranie pomocou kľúčového slova „extends“. | Rozhranie nemôže implementovať iné rozhranie pomocou kľúčových slov „implementuje“. |
Môže abstraktná trieda implementovať rozhranie v Jave
Áno, abstraktná trieda môže implementovať rozhranie pomocou kľúčového slova „implements“. Abstraktná trieda nemusí implementovať všetky abstraktné metódy rozhrania. Ale celkovo je dobrým návrhovým postupom mať rozhranie so všetkými abstraktnými metódami, potom abstraktnú triedu implementujúcu toto rozhranie a potom konkrétne triedy.
Nižšie je uvedený príklad takejto implementácie v Jave.
Tu je rozhranie java.util.List. Toto rozhranie implementuje java.util.AbstractList. Potom je táto trieda AbstractList rozšírená o dve konkrétne triedy, tj. LinkedList a ArrayList.
Keby triedy LinkedList a ArrayList implementovali rozhranie List priamo, potom by museli implementovať všetky abstraktné metódy rozhrania List.
Ale v tomto prípade trieda AbstractList implementuje metódy rozhrania List a odovzdáva ich ďalej LinkedList a ArrayList. Takže tu máme výhodu deklarovania typu z rozhrania a flexibility abstraktnej triedy pri implementácii spoločného správania.
Kedy použiť abstraktnú triedu a rozhranie v Jave
Abstraktnú triedu používame hlavne na definovanie predvoleného alebo bežného správania podradených tried, ktoré bude vychádzať z tejto abstraktnej triedy. Rozhranie sa používa na definovanie zmluvy medzi dvoma systémami, ktoré interagujú v aplikácii.
Určité konkrétne situácie sú ideálne na použitie rozhraní a určité problémy, ktoré je možné vyriešiť iba pomocou abstraktných tried. V tejto časti si rozoberieme, kedy môžeme používať rozhranie a kedy môžeme používať abstraktné triedy.
Kedy použiť rozhranie:
- Rozhrania sa používajú hlavne vtedy, keď máme na implementáciu malú výstižnú funkčnosť.
- Keď implementujeme rozhrania API a vieme, že sa na chvíľu nezmenia, potom pôjdeme po rozhraniach.
- Rozhrania nám umožňujú implementovať viacnásobné dedičstvo. Preto keď potrebujeme do našej aplikácie implementovať viacnásobné dedenie, ideme na rozhrania.
- Keď máme širokú škálu objektov, opäť sú lepšou voľbou rozhrania.
- Aj keď musíme poskytnúť spoločnú funkčnosť mnohým nesúvisiacim triedam, použijú sa stále rozhrania.
Kedy použiť abstraktnú triedu:
- Abstraktné triedy sa používajú hlavne vtedy, keď v našej aplikácii potrebujeme použiť dedičnosť.
- Pretože rozhrania pracujú s verejnými metódami a premennými, kedykoľvek chceme v našom programe použiť neverejné modifikátory prístupu, použijeme abstraktné triedy.
- Ak je potrebné pridať nové metódy, je lepšie to urobiť v abstraktnej triede ako v rozhraní. Pretože ak do rozhrania pridáme novú metódu, celá implementácia sa zmení, pretože rozhrania majú iba prototypy metód a implementáciu zabezpečí implementácia triedy pomocou rozhrania.
- Ak chceme, aby sa vyvíjali rôzne verzie komponentov, ideme na abstraktnú triedu. Abstraktné triedy môžeme meniť jednoduchšie. Rozhrania sa však nedajú zmeniť. Ak chceme novú verziu, musíme znova napísať celé rozhranie.
- Ak chceme poskytnúť spoločnú implementáciu pre všetky komponenty, potom je najlepšou voľbou abstraktná trieda.
Rozhranie Vs Abstraktná trieda v Jave
Ďalej uvádzame niektoré rozdiely medzi triedami Interfaces a Abstract v jazyku Java.
Rozhranie | Abstraktná trieda |
---|---|
Rozhranie sa deklaruje pomocou kľúčového slova „interface“. | Abstraktná trieda sa deklaruje pomocou kľúčového slova „abstract“. |
Rozhranie je možné implementovať pomocou kľúčového slova „implements“. | Abstrakt je možné dediť pomocou kľúčového slova „extends“. |
Rozhranie nemôže rozšíriť triedu alebo implementovať rozhranie, môže rozšíriť iba ďalšie rozhranie. | Abstraktná trieda môže rozšíriť triedu alebo implementovať viac rozhraní. |
Členovia rozhrania môžu byť iba verejní. | Členovia abstraktnej triedy môžu byť verejní, súkromní alebo chránení. |
Na zabezpečenie implementácie nemožno použiť rozhranie. Môže sa použiť iba ako vyhlásenie. | Na implementáciu rozhrania je možné použiť abstraktnú triedu. |
Pomocou rozhraní je možné dosiahnuť viacnásobné dedičstvo. | Abstraktná trieda nepodporuje viacnásobné dedenie. |
Rozhrania môžu mať iba abstraktné metódy. Z Java 8 môže mať statické a predvolené metódy. | Abstraktná trieda môže mať abstraktnú alebo neabstraktnú metódu. |
Enum dedičnosť v Jave
Diskutovali sme o dátových typoch enum v našej diskusii o dátových typoch v Jave. Všetky enumy siahajú od triedy java.lang.Enum. Táto trieda java.lang.Enum je abstraktná trieda.
Všetky triedy enum v jazyku Java sú tiež predvolene „konečné“. Preto pokus o zdedenie triedy z akýchkoľvek tried enum vedie k chybe kompilátora.
Pretože Java nepovoľuje viacnásobné dedenie, nemôžeme dediť triedu enum z inej triedy, pretože trieda enum už dedí z java.lang.Enum. Triedy enum však môžu implementovať rozhrania v Jave a toto sa nazýva Enum dedičnosť v Jave.
Nižšie je uvedený príklad dedičnosti Enum v Jave.
//WeekDays interface declaration interface WeekDays { public void displaydays(); } //enum class implementing WeekDays interface enum Days implements WeekDays { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY,FRIDAY, SATURDAY; public void displaydays() { //Override displaydays method System.out.println('The day of the week: ' + this); } } class Main { public static void main(String() args) { Days.MONDAY.displaydays(); //access enum value } }
Výkon:
Tu máme rozhranie WeekDays s abstraktnou metódou prototyp displaydays (). Potom definujeme enum triedu Days, ktorá implementuje rozhranie WeekDays. Tu definujeme enum hodnoty od NEDEĽA do SOBOTU a tiež prepíšeme metódu displaydays.
Nakoniec v hlavnej metóde sprístupníme hodnotu enum a zobrazíme ju.
často kladené otázky
Otázka č. 1) Čo sa stane, ak v rozhraní zadáte telo metódy?
Odpoveď: Pre verzie Java staršie ako Java 8 nie je telo metódy povolené v rozhraní. Od verzie Java 8 však môžeme v rozhraní definovať predvolenú alebo statickú metódu.
Otázka 2) Môže mať rozhranie v Java 8 premenné?
Odpoveď: V Jave 8 môžeme mať konštantné premenné pomocou statických a konečných modifikátorov. Ale nemôžeme mať inštančné premenné v rozhraniach Java. Akýkoľvek pokus o vyhlásenie premenných inštancie v rozhraní bude mať za následok chybu kompilátora.
Otázka č. 3) Aké sú vylepšenia rozhraní v prostredí Java 8?
Odpoveď: Najdôležitejším vylepšením rozhraní v prostredí Java 8 je to, že v rozhraniach sú povolené statické a predvolené metódy. Môžeme mať metódy deklarované ako statické alebo predvolené a definovať ich vo vnútri rozhrania.
Otázka č. 4) Môžeme prepísať predvolenú metódu v rozhraní Java?
Odpoveď: Nie. Nie je povinné prepísať predvolenú metódu v rozhraní. Je to tak preto, lebo keď implementujeme rozhranie v triede, potom je predvolená metóda triedy prístupná implementačnej triede. Preto pomocou objektu implementačnej triedy môžeme získať prístup k predvolenej metóde rozhrania.
Otázka č. 5) Môžu rozhrania obsahovať polia v Jave?
aký je najlepší sťahovač hudby pre Android
Odpoveď: Áno, v rozhraniach v Jave môžeme mať polia alebo premenné, ale štandardne sú všetky tieto polia statické, konečné a verejné.
Záver
V tomto tutoriáli sme diskutovali o zmenách vykonaných v rozhraniach v prostredí Java 8. Java 8 zaviedla v rozhraniach statické a predvolené metódy. Predtým sme v rozhraní mohli mať iba abstraktné metódy. Ale od Javy 8 a ďalej môžeme v Jave definovať predvolené a statické metódy.
Java 8 tiež umožňuje použitie výrazov lambda s funkčnými rozhraniami v jazyku Java. Potom sme tiež diskutovali o abstraktných triedach a rozhraniach a videli sme, kedy ich použiť v Jave. Videli sme tiež dedenie enum v Jave.
Diskutovali sme tiež o niektorých rozdieloch medzi rozšíreniami a implementáciami, triedou a rozhraním, abstraktnou triedou a rozhraním atď.
=> Skontrolujte VŠETKY návody Java tu.
Odporúčané čítanie
- Príručka k rozhraniu Java a abstraktnej triede
- Porovnateľné a porovnávacie rozhrania v Jave
- Rozhranie ListIterator v Jave s príkladmi
- Nastaviť rozhranie v prostredí Java: Výukový program sady Java s príkladmi
- Rozhranie značiek v Jave: Serializovateľné a klonovateľné
- Metóda Java String length () s príkladmi
- Nasadenie Java: Vytvorenie a vykonanie súboru Java JAR
- Ako používať metódu Java toString?