Statičke i zadane metode u sučeljima na Javi

1. Pregled

Java 8 donijela je na stol nekoliko potpuno novih značajki, uključujući lambda izraze, funkcionalna sučelja, reference metoda, strujanja, opcionalno i statički i zadano metode u sučeljima.

Neki od njih već su obrađeni u ovom članku. Ipak, statički i zadano metode u sučeljima same zaslužuju dublji uvid.

U ovom ćemo članku detaljno raspraviti kako koristiti statički i zadano metode u sučeljima i proći kroz neke slučajeve upotrebe gdje mogu biti korisni.

2. Zašto su potrebne zadane metode u sučeljima

Poput uobičajenih metoda sučelja, zadane metode su implicitno javne - nema potrebe za specificiranjem javnost modifikator.

Za razliku od uobičajenih metoda sučelja, jesu proglašen s zadano ključna riječ na početku potpisa metode, i oni osigurati provedbu.

Pogledajmo jednostavan primjer:

javno sučelje MyInterface {// redovite metode sučelja default void defaultMethod () {// implementacija zadane metode}}

Razlog zašto zadano metode uključene u izdanje Java 8 prilično je očito.

U tipičnom dizajnu koji se temelji na apstrakcijama, gdje sučelje ima jednu ili više implementacija, ako se sučelju doda jedna ili više metoda, sve će implementacije biti prisiljene primijeniti ih također. Inače, dizajn će se jednostavno pokvariti.

Zadane metode sučelja učinkovit su način rješavanja ovog problema. Oni dopustite nam da sučelju dodamo nove metode koje su automatski dostupne u implementacijama. Dakle, nema potrebe za modificiranjem klasa implementacije.

Na ovaj način, povratna kompatibilnost je uredno očuvana a da ne treba refaktorirati realizatore.

3. Zadane metode sučelja na djelu

Da bismo bolje razumjeli funkcionalnost zadano metode sučelja, stvorimo jednostavan primjer.

Recimo da imamo naivnog Vozilo sučelje i samo jedna implementacija. Moglo bi biti i više, ali neka bude tako jednostavno:

javno sučelje Vozilo {String getBrand (); String speedUp (); Niz slowDown (); zadani String turnAlarmOn () {return "Uključivanje alarma u vozilu."; } zadani niz TurnAlarmOff () {return "Isključivanje alarma u vozilu."; }}

I napišimo klasu implementacije:

automobil javne klase Vozilo {marka privatnog niza; // konstruktori / getteri @Override public String getBrand () {return brand; } @Override public String speedUp () {return "Auto ubrzava."; } @Override public String slowDown () {return "Auto usporava."; }} 

Na kraju, definirajmo tipično glavni klase, koja stvara instancu Automobil i poziva svoje metode:

public static void main (String [] args) {Vozilo = novi automobil ("BMW"); System.out.println (car.getBrand ()); System.out.println (car.speedUp ()); System.out.println (car.slowDown ()); System.out.println (car.turnAlarmOn ()); System.out.println (car.turnAlarmOff ()); }

Primijetite kako zadano metode turnAlarmOn () i turnAlarmOff () od našeg Vozilo sučelje su automatski dostupan u Automobil razred.

Nadalje, ako u nekom trenutku odlučimo dodati još zadano metode za Vozilo sučelje, aplikacija će i dalje nastaviti raditi i nećemo morati prisiljavati klasu da osigura implementacije novih metoda.

Najtipičnija uporaba zadanih metoda u sučeljima je za postepeno pružanje dodatne funkcionalnosti određenom tipu bez raščlanjivanja izvedbenih klasa.

Osim toga, na njih se mogu naviknuti pružaju dodatnu funkcionalnost oko postojeće apstraktne metode:

javno sučelje Vozilo {// dodatne metode sučelja double getSpeed ​​(); zadana dvostruka getSpeedInKMH (dvostruka brzina) {// pretvorba}}

4. Više pravila nasljeđivanja sučelja

Zadane metode sučelja doista su prilično lijepa značajka, ali uz neke napomene koje vrijedi spomenuti. Budući da Java dopušta da klase implementiraju više sučelja, važno je znati što se događa kada klasa implementira nekoliko sučelja koja definiraju isto zadano metode.

Da bismo bolje razumjeli ovaj scenarij, definirajmo novi Alarm sučelje i refaktor Automobil razred:

javno sučelje Alarm {zadani niz turnAlarmOn () {return "Uključivanje alarma."; } zadani niz TurnAlarmOff () {return "Isključivanje alarma."; }}

Ovim novim sučeljem definira vlastiti skup zadano metode, Automobil razred bi implementirao oboje Vozilo i Alarm:

auto javne klase Vozilo, alarm {// ...}

U ovom slučaju, kod se jednostavno neće kompajlirati, jer postoji sukob uzrokovan nasljeđivanjem više sučelja (poznat kao problem s dijamantima). The Automobil klasa naslijedila bi oba skupa zadano metode. Koje bi tada trebalo nazvati?

Da bismo riješili tu dvosmislenost, moramo izričito osigurati provedbu metoda:

@Override javni niz turnAlarmOn () {// prilagođena implementacija} @Override javni niz turnAlarmOff () {// prilagođena implementacija}

Možemo i mi neka naš razred koristi zadano metode jednog od sučelja.

Pogledajmo primjer koji koristi zadano metode iz Vozilo sučelje:

@Override public String turnAlarmOn () {return Vehicle.super.turnAlarmOn (); } @Override public String turnAlarmOff () {return Vehicle.super.turnAlarmOff (); } 

Slično tome, možemo razredu koristiti zadano metode definirane unutar Alarm sučelje:

@Override public String turnAlarmOn () {return Alarm.super.turnAlarmOn (); } @Override public String turnAlarmOff () {return Alarm.super.turnAlarmOff (); } 

Nadalje, ujednačeno je moguće napraviti Automobil klasa koriste oba skupa zadanih metoda:

@Override public String turnAlarmOn () {return Vehicle.super.turnAlarmOn () + "" + Alarm.super.turnAlarmOn (); } @Override public String turnAlarmOff () {return Vehicle.super.turnAlarmOff () + "" + Alarm.super.turnAlarmOff (); } 

5. Metode statičkog sučelja

Osim što se može izjasniti zadano metode u sučeljima, Java 8 omogućuje nam definiranje i implementaciju statički metode u sučeljima.

Od statički metode ne pripadaju određenom objektu, nisu dio API-ja klasa koje implementiraju sučelje, a to moraju biti poziva se pomoću naziva sučelja koje prethodi imenu metode.

Da shvatim kako statički metode rade u sučeljima, preoblikujmo Vozilo sučelje i dodajte mu a statički korisna metoda:

javno sučelje Vozilo {// redovne / zadane metode sučelja static int getHorsePower (int rpm, int torque) {return (rpm * torque) / 5252; }} 

Utvrđivanje a statički metoda unutar sučelja identična je definiranju one u klasi. Štoviše, a statički metoda može se pozvati unutar druge statički i zadano metode.

Recite sada da želimo izračunati konjske snage motora određenog vozila. Samo zovemo getHorsePower () metoda:

Vehicle.getHorsePower (2500, 480)); 

Ideja koja stoji iza statički metode sučelja je pružanje jednostavnog mehanizma koji nam omogućuje povećati stupanj kohezije dizajna spajanjem srodnih metoda na jednom mjestu bez potrebe za stvaranjem predmeta.

Prilično isto se može učiniti sa apstraktnom nastavom. Glavna razlika leži u činjenici da apstraktne klase mogu imati konstruktore, stanje i ponašanje.

Nadalje, statičke metode u sučeljima omogućuju grupiranje srodnih korisnih metoda, bez potrebe za stvaranjem umjetnih klasa korisnih programa koje su jednostavno rezervirana mjesta za statičke metode.

6. Zaključak

U ovom smo članku detaljno istražili upotrebu statički i zadano metode sučelja u Javi 8. Na prvi pogled ova značajka može izgledati pomalo traljavo, posebno iz objektno orijentirane purističke perspektive. U idealnom slučaju, sučelja ne bi trebala sadržavati ponašanje i trebala bi se koristiti samo za definiranje javnog API-ja određenog tipa.

Međutim, što se tiče održavanja povratne kompatibilnosti s postojećim kodom, statički i zadano metode su dobra trgovina.

Kao i obično, svi uzorci koda prikazani u ovom članku dostupni su na GitHubu.