Sučelja
Sučelje u Javi pomalo je nalik klasi, ali sa značajnom razlikom: an interface
može imati samo potpise, polja i zadane metode. Od Jave 8 možete stvoriti i zadane metode. U sljedećem bloku možete vidjeti primjer sučelja:
public interface Vehicle { public String licensePlate = ""; public float maxVel public void start(); public void stop(); default void blowHorn(){ System.out.println("Blowing horn"); } }
Gornje sučelje sadrži dva polja, dvije metode i zadanu metodu. Sam nije od velike koristi, ali obično se koristi zajedno s nastavom. Kako? Jednostavno, morate se pobrinuti da ga neki predaju implements
.
public class Car implements Vehicle { public void start() { System.out.println("starting engine..."); } public void stop() { System.out.println("stopping engine..."); } }
Sada postoji osnovno pravilo : Klasa mora implementirati sve metode u sučelju. Metode moraju imati potpuno isti potpis (ime, parametri i iznimke) kao što je opisano u sučelju. Klasa ipak ne treba deklarirati polja, već samo metode.
Primjerci sučelja
Jednom kada stvorite Java klasu na implements
bilo kojem sučelju, instanca objekta može se referencirati kao instanca sučelja. Ovaj je koncept sličan konceptu nasljeđivanja.
// following our previous example Vehicle tesla = new Car(); tesla.start(); // starting engine ...
Sučelje ne može sadržavati metode konstruktora. Stoga ne možete stvoriti instancu samog sučelja. Morate stvoriti instancu neke klase koja implementira sučelje da bi ga referencirali.
Zamišljajte sučelja kao prazan obrazac ugovora ili predložak.
Što možete učiniti s ovom značajkom? Polimorfizam! Možete koristiti samo sučelja za pozivanje na instance objekta!
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 ...
Ali što kažete na više sučelja?
Da, možete implementirati više sučelja u jednoj klasi. Dok ste u nasljeđivanju unutar klasa imali ograničenje da nasljeđujete samo jednu klasu, ovdje možete proširiti bilo koji broj sučelja. Ali ne zaboravite primijeniti sve metode svih sučelja, inače kompilacija neće uspjeti!
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 } }
Neke značajke sučelja
- Varijable možete smjestiti unutar sučelja, iako to neće biti razumna odluka jer razredi ne moraju imati istu varijablu. Ukratko, izbjegavajte postavljanje varijabli!
- Sve su varijable i metode u sučelju javne, čak i ako izostavite
public
ključnu riječ. - Sučelje ne može odrediti provedbu određene metode. Na klasama je da to učine. Iako je nedavno došlo do iznimke (vidi dolje).
- Ako klasa implementira više sučelja, postoji velika vjerojatnost preklapanja potpisa metode. Budući da Java ne dopušta više metoda potpuno istog potpisa, to može dovesti do problema. Pogledajte ovo pitanje za više informacija.
Zadane metode sučelja
Prije Jave 8 nismo imali načina usmjeriti sučelje da bi se primijenila određena metoda. To dovodi do velike zabune i prekida koda ako se iznenada promijeni definicija sučelja.
Pretpostavimo da ste napisali biblioteku otvorenog koda koja sadrži sučelje. Recimo, vaši klijenti, tj. Praktički svi programeri širom svijeta, to jako koriste i sretni su. Sada ste morali nadograditi knjižnicu dodavanjem nove definicije metode u Sučelje kako bi podržala novu značajku. Ali to bi prekinulo sve gradnje, jer se sve klase koje implementiraju to sučelje moraju promijeniti sada. Kakva katastrofa!
Srećom, Java 8 nam sada nudi default
metode za sučelja. default
Metoda može sadržavati vlastiti provedbu izravno u sučelju! Dakle, ako klasa ne implementira zadanu metodu, prevoditelj će poduzeti implementaciju spomenutu u sučelju. Lijepo, zar ne? Dakle, u svoju biblioteku možete dodati bilo koji broj zadanih metoda u sučelja bez straha da ćete nešto slomiti!
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...
Ali, što se događa ako dva sučelja imaju isti potpis metode?
Sjajno pitanje. U tom slučaju, ako ne osigurate implementaciju u klasi, loši kompajler će se zbuniti i jednostavno neće uspjeti! Morate osigurati i zadanu implementaciju metode unutar Klase. Postoji i izvrstan način super
da pozovete koja vam se implementacija sviđa:
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
Statičke metode u sučeljima
Također je novo za Javu 8 mogućnost dodavanja statičkih metoda u sučelja. Statičke metode u sučeljima gotovo su identične statičkim metodama u konkretnim klasama. Jedina velika razlika je u tome što se static
metode ne nasljeđuju u klasama koje implementiraju sučelje. To znači da se na sučelje poziva kada se poziva statička metoda, a ne klasa koja je implementira.
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 } }
Nasljeđivanje sučelja
U Javi je također moguće da sučelje naslijedi drugo sučelje, koristeći, pogađate, extends
ključnu riječ:
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"); } }
To znači da MusicPlayer
sučelje koje implementira klasu mora implementirati sve metode MusicPlayer
kao i 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"); } }
Dakle, sada dobro razumijete Java sučelja! Krenite učiti o tečajevima sažetka da biste vidjeli kako vam Java daje još jedan način definiranja ugovora.