Ohjelmointi

Liitännät Java: ssa

Java-käyttöliittymät eroavat luokista, ja on tärkeää tietää, miten niiden erityisominaisuuksia käytetään Java-ohjelmissa. Tämä opetusohjelma esittelee luokkien ja käyttöliittymien välisen eron ja opastaa sitten esimerkkejä Java-käyttöliittymien julistamisesta, toteuttamisesta ja laajentamisesta.

Opit myös, kuinka käyttöliittymä on kehittynyt Java 8: ssa, lisäämällä oletus- ja staattiset menetelmät, ja Java 9: ​​ssä uusilla yksityisillä menetelmillä. Nämä lisäykset tekevät käyttöliittymistä hyödyllisempiä kokeneille kehittäjille. Valitettavasti ne hämärtävät myös luokkien ja rajapintojen väliset linjat, mikä tekee käyttöliittymän ohjelmoinnista entistä hämmentävämpää Java-aloittelijoille.

lataa Hanki koodi Lataa lähdekoodi esimerkiksi sovelluksiin tässä opetusohjelmassa. Luonut Jeff Friesen JavaWorldille.

Mikä on Java-käyttöliittymä?

An käyttöliittymä on kohta, jossa kaksi järjestelmää kohtaavat ja ovat vuorovaikutuksessa. Voit esimerkiksi käyttää myyntiautomaatin käyttöliittymää valitaksesi tuotteen, maksaa siitä ja vastaanottaa ruoka- tai juomatuotteen. Ohjelmoinnin näkökulmasta ohjelmistokomponenttien välillä on rajapinta. Ota huomioon, että menetelmän otsikon (menetelmän nimi, parametriluettelo ja niin edelleen) liitäntä sijaitsee menetelmää kutsuvan ulkoisen koodin ja menetelmän sisällä olevan koodin välillä, joka suoritetaan puhelun seurauksena. Tässä on esimerkki:

System.out.println (keskiarvo (10, 15)); kaksinkertainen keskiarvo (kaksinkertainen x, kaksinkertainen y) // rajapinta keskimääräisen (10, 15) puhelun ja paluun (x + y) / 2 välillä; {paluu (x + y) / 2; }

Java-aloittelijoille on usein hämmentävää, että luokilla on myös käyttöliittymät. Kuten selitin Java 101: ssa: Java-luokat ja objektit, käyttöliittymä on luokan osa, johon pääsee sen ulkopuolella sijaitsevalle koodille. Luokan rajapinta koostuu jostakin yhdistelmästä menetelmiä, kenttiä, rakentajia ja muita kokonaisuuksia. Harkitse listaa 1.

Listaus 1. Tililuokka ja sen käyttöliittymä

luokan tili {yksityinen merkkijono nimi; yksityinen pitkä summa; Tili (merkkijonon nimi, pitkä summa) {this.name = nimi; setAmount (määrä); } mitätöity talletus (pitkä summa) {tämä.summa + = summa; } Merkkijono getName () {return name; } pitkä getAmount () {palautussumma; } void setAmount (pitkä summa) {this.amount = summa; }}

Tili (merkkijonon nimi, pitkä summa) rakentaja ja mitätöity talletus (pitkä summa), Merkkijono getName (), pitkä getAmount ()ja void setAmount (pitkä summa) menetelmät muodostavat Tili luokan käyttöliittymä: ne ovat ulkoisen koodin käytettävissä. yksityinen merkkijono nimi; ja yksityinen pitkä summa; kentät eivät ole käytettävissä.

Lisätietoja Java-käyttöliittymistä

Mitä voit tehdä Java-ohjelmiesi liitäntöjen kanssa? Hanki yleiskatsaus Jeffin Java-käyttöliittymän kuudesta roolista.

Menetelmän koodi, joka tukee menetelmän käyttöliittymää, ja luokan osa, joka tukee luokan käyttöliittymää (kuten yksityiset kentät), tunnetaan menetelmän tai luokan toteutus. Toteutus tulee piilottaa ulkoiselta koodilta, jotta se voidaan muuttaa vastaamaan muuttuvia vaatimuksia.

Kun toteutukset paljastuvat, ohjelmistokomponenttien välillä voi syntyä keskinäisiä riippuvuuksia. Esimerkiksi menetelmäkoodi voi luottaa ulkoisiin muuttujiin ja luokan käyttäjät voivat olla riippuvaisia ​​kentistä, jotka olisi pitänyt piilottaa. Tämä kytkentä voi johtaa ongelmiin, kun toteutusten on kehittyttävä (ehkä paljaat kentät on poistettava).

Java-kehittäjät käyttävät käyttöliittymän kieliominaisuutta luokkien rajapintojen abstraktioon irrotus luokkien käyttäjiltä. Keskittymällä Java-rajapintoihin luokkien sijasta, voit minimoida lähdekoodisi viittausten luokan nimiin. Tämä helpottaa vaihtamista luokasta toiseen (ehkä suorituskyvyn parantamiseksi) ohjelmiston kypsyessä. Tässä on esimerkki:

Luettelon nimet = new ArrayList () void print (Luettelon nimet) {// ...}

Tämä esimerkki ilmoittaa ja alustaa a nimet kenttä, joka tallentaa luettelon merkkijonojen nimistä. Esimerkissä julistetaan myös a Tulosta() tapa tulostaa merkkijonoluettelon sisältö, ehkä yksi merkkijono riviä kohden. Lyhyesti sanottuna olen jättänyt menetelmän toteutuksen pois.

Lista on Java-käyttöliittymä, joka kuvaa peräkkäistä objektien kokoelmaa. ArrayList on luokka, joka kuvaa taulukon matriisipohjaista toteutusta Lista Java-käyttöliittymä. Uusi esimerkki ArrayList luokka saadaan ja osoitetaan Lista muuttuja nimet. (Lista ja ArrayList tallennetaan tavallisiin luokkakirjastoihin java.util paketti.)

Kulmasulkeet ja geneeriset tuotteet

Kulmasulkeet (< ja >) ovat osa Java: n geneerisiä ominaisuuksia. Ne osoittavat sen nimet kuvaa merkkijonoluettelon (luetteloon voi tallentaa vain merkkijonoja). Esittelen geneeriset tuotteet tulevassa Java 101 -artikkelissa.

Kun asiakaskoodi on vuorovaikutuksessa nimet, se käyttää niitä menetelmiä, jotka Listaja jotka toteuttaa ArrayList. Asiakaskoodi ei ole suorassa vuorovaikutuksessa ArrayList. Tämän seurauksena asiakaskoodi ei riko, kun eri toteutusluokka, kuten LinkedList, vaaditaan:

Luettelonimet = new LinkedList () // ... void print (Luettelonimet) {// ...}

Koska Tulosta() method-parametrin tyyppi on Lista, tämän menetelmän toteutuksen ei tarvitse muuttua. Kuitenkin, jos tyyppi olisi ollut ArrayList, tyyppi olisi vaihdettava muotoon LinkedList. Jos molemmat luokat julistaisivat omat ainutlaatuiset menetelmänsä, sinun on ehkä muutettava merkittävästi Tulosta()täytäntöönpanoa.

Irrotus Lista alkaen ArrayList ja LinkedList voit kirjoittaa koodin, joka on immuuni luokan toteutuksen muutoksille. Java-käyttöliittymiä käyttämällä voit välttää ongelmat, joita saattaa syntyä luottaessa toteutusluokkiin. Tämä irrotus on tärkein syy Java-käyttöliittymien käyttöön.

Java-käyttöliittymien ilmoittaminen

Ilmoitat käyttöliittymän noudattamalla luokan kaltaista syntaksia, joka koostuu otsikosta ja rungosta. Vähintään otsikko koostuu avainsanasta käyttöliittymä jota seuraa käyttöliittymän tunnistava nimi. Runko alkaa avoimella ahdinmerkillä ja päättyy sulkeilla. Näiden erottimien välissä on vakio ja metodin otsikkomerkinnät:

käyttöliittymä tunniste {// käyttöliittymän runko}

Tavanomaisesti käyttöliittymän nimen ensimmäinen kirjain on isoja ja seuraavia kirjaimia pieniä (esimerkiksi Piirrettävä). Jos nimi koostuu useammasta sanasta, jokaisen sanan ensimmäinen kirjain kirjoitetaan isolla kirjaimella (kuten DrawableAndFillable). Tämä nimeämiskäytäntö tunnetaan nimellä CamelCasing.

Listaus 2 julistaa käyttöliittymän nimeltä Piirrettävä.

Luettelo 2. Java-käyttöliittymäesimerkki

käyttöliittymä Piirrettävä {int PUNAINEN = 1; int VIHREÄ = 2; int SININEN = 3; int MUSTA = 4; int VALKOINEN = 5; mitätön piirtäminen (int väri); }

Liitännät Javan vakioluokkikirjastossa

Nimeämiskäytäntönä monet Java: n vakioluokan kirjastossa olevat käyttöliittymät päättyvät pystyy pääte. Esimerkkejä ovat Soitettava, Kloonattava, Vertailukelpoinen, Alustettava, Iterable, Ajettava, Sarjattavissaja Siirrettävissä. Pääte ei kuitenkaan ole pakollinen; tavallinen luokan kirjasto sisältää rajapinnat CharSequence, LeikepöytäOmistaja, Kokoelma, Suorittaja, Tulevaisuus, Iteraattori, Lista, Kartta ja monet muut.

Piirrettävä julistaa viisi kenttää, jotka tunnistavat värivakiot. Tämä käyttöliittymä ilmoittaa myös a: n otsikon piirtää () menetelmä, joka on kutsuttava yhdellä näistä vakioista määrittelemään väri, jota käytetään ääriviivan piirtämiseen. (Luku vakioiden käyttö ei ole hyvä idea, koska mikä tahansa kokonaislukuarvo voidaan välittää piirtää (). Ne kuitenkin riittävät yksinkertaisessa esimerkissä.)

Kentän ja menetelmän otsikon oletukset

Liitännässä ilmoitetut kentät ovat implisiittisesti julkinen lopullinen staattinen. Rajapinnan menetelmän otsikot ovat implisiittisesti julkinen abstrakti.

Piirrettävä tunnistaa viitetyypin, joka määrittää mitä tehdä (piirtää jotain), mutta ei miten se tehdään. Toteutustiedot lähetetään luokille, jotka toteuttavat tämän käyttöliittymän. Tällaisten luokkien esiintymiä kutsutaan nostettaviksi, koska he osaavat piirtää itseään.

Marker- ja tagging-rajapinnat

Rajapinta tyhjän rungon kanssa tunnetaan nimellä merkkiliitäntä tai a koodausliittymä. Käyttöliittymä on olemassa vain metatietojen liittämiseksi luokkaan. Esimerkiksi, Kloonattava (katso Inheritance in Java, osa 2) tarkoittaa, että sen toteutusluokan esiintymät voidaan kloonata matalasti. Kun Esineon klooni() method havaitsee (ajonaikaisen tyypin tunnistuksen kautta), että kutsuvan ilmentymän luokka toteuttaa Kloonattava, se kloonaa kohteen matalasti.

Java-rajapintojen käyttöönotto

Luokka toteuttaa käyttöliittymän liittämällä Java: t työvälineet avainsana, jota seuraa pilkuilla erotettu luettelo käyttöliittymän nimistä luokan otsikkoon ja koodaamalla jokainen luokan käyttöliittymämenetelmä. Listing 3 esittää luokan, joka toteuttaa Listing 2: n Piirrettävä käyttöliittymä.

Listaus 3. Piiri, joka toteuttaa Drawable-käyttöliittymän

luokan ympyrätyökalut Piirrettävä {yksityinen kaksinkertainen x, y, säde; Ympyrä (kaksinkertainen x, kaksinkertainen y, kaksinkertainen säde) {this.x = x; tämä.y = y; tämä.säde = säde; } @Override public void draw (int color) {System.out.println ("Ympyrä piirretty (" + x + "," + y + "), säde" + säde + "ja väri" + väri); } double getRadius () {paluusäde; } tuplasti getX () {return x; } kaksinkertainen getY () {return y; }}

Luettelo 3: sta Ympyrä luokka kuvaa ympyrää keskipisteenä ja säteenä. Sen lisäksi, että tarjotaan rakentaja ja sopivat getter-menetelmät, Ympyrä toteuttaa Piirrettävä käyttöliittymä liittämällä työkalut Piirrettävissä että Ympyrä otsikossa ja ohittamalla (kuten @Ohittaa merkintä) Piirrettäväon piirtää () method-otsikko.

Luettelossa 4 on toinen esimerkki: a Suorakulmio luokka, joka myös toteuttaa Piirrettävä.

Luettelo 4. Piirrettävän käyttöliittymän toteuttaminen suorakulmion yhteydessä

luokan suorakulmion työkalut Piirrettävä {yksityinen kaksinkertainen x1, y1, x2, y2; Suorakulmio (kaksinkertainen x1, kaksinkertainen y1, kaksinkertainen x2, kaksinkertainen y2) {tämä.x1 = x1; tämä.y1 = y1; tämä.x2 = x2; tämä.y2 = y2; } @Override public void draw (int color) {System.out.println ("Suorakulmio piirretty vasemmassa yläkulmassa kohdassa (" + x1 + "," + y1 + ") ja oikeassa alakulmassa kohdassa (" + x2 + "," + y2 + ") ja väri" + väri); } kaksois getX1 () {return x1; } tuplasti getX2 () {return x2; } kaksois getY1 () {return y1; } kaksois getY2 () {return y2; }}

Listaus 4: stä Suorakulmio luokka kuvaa suorakulmion pisteparina, joka merkitsee tämän muodon vasenta ja oikeaa alakulmaa. Kuten Ympyrä, Suorakulmio tarjoaa rakentajan ja sopivat getter-menetelmät sekä toteuttaa Piirrettävä käyttöliittymä.

Liitäntämenetelmän otsikoiden korvaaminen

Kääntäjä ilmoittaa virheestä, kun yrität koota ei-abstrakti luokka, joka sisältää työvälineet käyttöliittymälauseke, mutta se ei korvaa kaikkia käyttöliittymän menetelmäotsikoita

Liitäntätyypin data-arvot ovat objekteja, joiden luokat toteuttavat käyttöliittymän ja joiden käyttäytyminen on käyttöliittymän menetelmäotsikoissa määritelty. Tämä tarkoittaa, että voit määrittää objektin viitteen rajapintatyypin muuttujalle edellyttäen, että objektin luokka toteuttaa rajapinnan. Listaus 5 osoittaa.

Listaus 5. Aliasing Circle and Rectangle -objektit piirrettävinä

luokka Piirrä {public static void main (String [] args) {Drawable [] drawables = new Drawable [] {new Circle (10, 20, 15), new Circle (30, 20, 10), new Rectangle (5, 8) , 8, 9)}; (int i = 0; i <vedettävissä.pituus; i ++) -piirustuksissa [i] .piirrä (Piirrettävä.PUNAINEN); }}

Koska Ympyrä ja Suorakulmio toteuttaa Piirrettävä, Ympyrä ja Suorakulmio esineillä on Piirrettävä tyyppi luokkatyyppiensä lisäksi. Siksi on laillista tallentaa kunkin objektin viittaus ryhmään Piirrettäväs. Silmukka toistuu tämän taulukon yli kutsuen kutakin Piirrettävä esine piirtää () menetelmä piirtää ympyrä tai suorakulmio.

Olettaen, että luettelo 2 on tallennettu a Drawable.java lähdetiedosto, joka on samassa hakemistossa Circle.java, Suorakulmio. Javaja Piirrä. Java lähdetiedostot (jotka vastaavat luetteloita 3, 4 ja 5), ​​kokoavat nämä lähdetiedostot jommallakummalla seuraavista komentoriveistä:

javac Draw.java javac * .java

Suorita Piirrä seuraavasti:

java Draw

Ota huomioon seuraava tulos:

Ympyrä piirretty (10.0, 20.0), säde 15.0, ja väri 1 Ympyrä piirretty (30.0, 20.0), säde 10.0 ja väri 1 Suorakulmio piirretty vasemmassa yläkulmassa kohdassa (5.0, 8.0) ja oikeassa alakulmassa kohdassa (8,0, 9,0) ja väri 1

Huomaa, että voit myös luoda saman tuloksen määrittämällä seuraavat main () menetelmä:

public staattinen void main (String [] args) {ympyrä c = uusi ympyrä (10, 20, 15); c. piirtää (Drawable.RED); c = uusi ympyrä (30, 20, 10); c. piirtää (Drawable.RED); Suorakulmio r = uusi suorakulmio (5, 8, 8, 9); r.piirrä (Drawable.RED); }

Kuten näette, on hankalaa vedota toistuvasti kunkin objektin kohteisiin piirtää () menetelmä. Lisäksi se lisää ylimääräisen tavukoodin Piirräluokan luokkatiedosto. Ajattelemalla Ympyrä ja Suorakulmio kuten Piirrettäväs, voit hyödyntää taulukkoa ja yksinkertaista silmukkaa koodin yksinkertaistamiseksi. Tämä on ylimääräinen etu koodin suunnittelusta liittymien suosimiseksi luokkien sijaan.

Varoitus!