Näidetega selgitatud Java-liidesed

Liidesed

Java-liides sarnaneb natuke klassiga, kuid olulise erinevusega: an-il interfacevõib olla ainult meetodi allkirju, väljad ja vaikemeetodid. Alates Java 8-st saate luua ka vaikemeetodeid. Järgmises plokis näete liidese näidet:

public interface Vehicle { public String licensePlate = ""; public float maxVel public void start(); public void stop(); default void blowHorn(){ System.out.println("Blowing horn"); } }

Eespool olev liides sisaldab kahte välja, kahte meetodit ja vaikemeetodit. Üksinda pole sellest palju kasu, kuid neid kasutatakse tavaliselt koos klassidega. Kuidas? Lihtne, peate veenduma, et keegi seda klassiks implementstunneb.

public class Car implements Vehicle { public void start() { System.out.println("starting engine..."); } public void stop() { System.out.println("stopping engine..."); } }

Nüüd kehtib põhireegel : klass peab rakendama kõik liidese meetodid. Meetoditel peab olema täpselt sama allkiri (nimi, parameetrid ja erandid), nagu on kirjeldatud liideses. Klassil pole siiski vaja väljad deklareerida, vaid ainult meetodid.

Liidese eksemplarid

Kui olete loonud mis implementstahes liidese Java-klassi , saab objekti eksemplari viidata liidese eksemplarile. See kontseptsioon sarnaneb pärandi eksponeerimisega.

// following our previous example Vehicle tesla = new Car(); tesla.start(); // starting engine ...

Liides ei tohi sisaldada konstruktori meetodeid. Seetõttu ei saa te ise liidese eksemplari luua. Sellele viitamiseks peate looma liidese rakendava klassi klassi eksemplari.

Mõelge liidestest kui tühjast lepinguvormist või mallist.

Mida saate selle funktsiooniga teha? Polümorfism! Objektieksemplaridele viitamiseks võite kasutada ainult liideseid!

class Truck implements Vehicle { public void start() { System.out.println("starting truck engine..."); } public void stop() { System.out.println("stopping truck engine..."); } } class Starter { // static method, can be called without instantiating the class public static void startEngine(Vehicle vehicle) { vehicle.start(); } } Vehicle tesla = new Car(); Vehicle tata = new Truck(); Starter.startEngine(tesla); // starting engine ... Starter.startEngine(tata); // starting truck engine ...

Aga kuidas oleks mitme liidesega?

Jah, ühes klassis saate rakendada mitu liidest. Kui klasside pärimise osas oli teil lubatud pärida ainult üks klass, siis siin saate laiendada mis tahes arvu liideseid. Kuid ärge unustage rakendada kõigi liideste kõiki meetodeid, muidu koostamine ebaõnnestub!

public interface GPS { public void getCoordinates(); } public interface Radio { public void startRadio(); public void stopRadio(); } public class Smartphone implements GPS,Radio { public void getCoordinates() { // return some coordinates } public void startRadio() { // start Radio } public void stopRadio() { // stop Radio } }

Liideste mõned funktsioonid

  • Muutujaid saate paigutada liidesesse, ehkki see pole mõistlik otsus, kuna klassidel pole tingimata sama muutujat. Lühidalt öeldes vältige muutujate paigutamist!
  • Kõik liidese muutujad ja meetodid on avalikud, isegi kui jätate publicmärksõna välja.
  • Liides ei saa täpsustada konkreetse meetodi rakendamist. Klasside ülesanne on seda teha. Kuigi hiljuti on olnud erand (vt allpool).
  • Kui klass rakendab mitut liidest, on meetodi allkirja kattumise võimalus kaugel. Kuna Java ei võimalda mitut meetodit täpselt sama allkirjaga, võib see põhjustada probleeme. Lisateabe saamiseks vaadake seda küsimust.

Liidese vaikemeetodid

Enne Java 8 ei olnud meil mingit võimalust liidest liidese suunamiseks konkreetse meetodi juurutamiseks. Kui järsult muudetakse liidese määratlust, tekitab see palju segadust ja koodimurde.

Oletame, et kirjutasite avatud lähtekoodiga teegi, mis sisaldab liidest. Oletame, et teie kliendid, st praktiliselt kõik arendajad üle kogu maailma, kasutavad seda palju ja on õnnelikud. Nüüd olete pidanud raamatukogu täiendama, lisades liidesele uue meetodi definitsiooni, et uut funktsiooni toetada. Kuid see rikuks kõik järkud, kuna kõik seda liidest rakendavad klassid peavad nüüd muutuma. Milline katastroof!

Õnneks pakub Java 8 meile nüüd defaultliideste meetodeid. defaultMeetod võib sisaldada oma rakendamise otseselt jooksul Interface! Niisiis, kui klass ei rakenda vaikemeetodit, võtab kompilaator liideses nimetatud rakenduse. Tore, kas pole? Nii võite oma teeki lisada liidestesse suvalise arvu vaikemeetodeid, kartmata midagi rikkuda!

public interface GPS { public void getCoordinates(); default public void getRoughCoordinates() { // implementation to return coordinates from rough sources // such as wifi & mobile System.out.println("Fetching rough coordinates..."); } } public interface Radio { public void startRadio(); public void stopRadio(); } public class Smartphone implements GPS,Radio { public void getCoordinates() { // return some coordinates } public void startRadio() { // start Radio } public void stopRadio() { // stop Radio } // no implementation of getRoughCoordinates() } Smartphone motoG = new Smartphone(); motog.getRoughCoordinates(); // Fetching rough coordinates...

Aga mis juhtub, kui kahel liidesel on sama meetodi allkiri?

Äge küsimus. Sel juhul, kui te ei paku rakendust klassis, läheb kehv kompilaator segadusse ja lihtsalt ebaõnnestub! Klassis peate pakkuma ka vaikemeetodi rakendamise. Meeldiva superrakenduse helistamiseks on ka suurepärane viis :

public interface Radio { // public void startRadio(); // public void stopRadio(); default public void next() { System.out.println("Next from Radio"); } } public interface MusicPlayer { // public void start(); // public void pause(); // public void stop(); default public void next() { System.out.println("Next from MusicPlayer"); } } public class Smartphone implements Radio, MusicPlayer { public void next() { // Suppose you want to call MusicPlayer next MusicPlayer.super.next(); } } Smartphone motoG = new Smartphone(); motoG.next(); // Next from MusicPlayer

Staatilised meetodid liidestes

Samuti on Java 8 uus võimalus liideste staatiliste meetodite lisamiseks. Liideste staatilised meetodid on peaaegu identsed konkreetsete klasside staatiliste meetoditega. Ainus suur erinevus on see, staticet liidese rakendamise klassides pole meetodeid päritud. See tähendab, et liidesele viidatakse staatilise meetodi, mitte selle rakendava klassi kutsumisel.

interface MusicPlayer { public static void commercial(String sponsor) { System.out.println("Now for a message brought to you by " + sponsor); } public void play(); } class Smartphone implements MusicPlayer { public void play() { System.out.println("Playing from smartphone"); } } class Main { public static void main(String[] args) { Smartphone motoG = new Smartphone(); MusicPlayer.commercial("Motorola"); // Called on interface not on implementing class // motoG.commercial("Motorola"); // This would cause a compilation error } }

Liidese pärimine

Java-s on liidesel võimalik pärida ka teine ​​liides, kasutades, arvate ära, extendsmärksõna:

public interface Player { public void start(); public void pause(); public void stop(); } public interface MusicPlayer extends Player { default public void next() { System.out.println("Next from MusicPlayer"); } }

See tähendab, klassi rakendamise MusicPlayerliides peab rakendama kõiki meetodeid MusicPlayersamuti Player:

public class SmartPhone implements MusicPlayer { public void start() { System.out.println("start"); } public void stop() { System.out.println("stop"); } public void pause() { System.out.println("pause"); } }

Nii et nüüd saate Java-liidestest hästi aru! Lisateavet abstraktsete klasside kohta saate teada, kuidas Java annab teile veel ühe võimaluse lepingute määratlemiseks.