Ohjelmointi

Sisäiset luokat

K: Joten mihin sisäiset luokat ovat hyviä?

A: Sisäiset luokat pesivät muissa luokissa. Normaali luokka on paketin suora jäsen, ylätason luokka. Sisäisillä luokilla, jotka tulivat saataville Java 1.1: llä, on neljä makua:

  • Staattiset jäsenluokat
  • Jäsenluokat
  • Paikalliset luokat
  • Nimetön luokat

Katsotaanpa nopeasti kutakin peräkkäin.

Lyhyesti sanottuna: a staattinen jäsenluokka on luokan staattinen jäsen. Kuten kaikilla muilla staattisilla menetelmillä, staattisella jäsenluokalla on pääsy kaikkiin vanhemman tai ylätason luokan staattisiin menetelmiin.

Kuten staattinen jäsenluokka, a jäsenluokka määritellään myös luokan jäseneksi. Toisin kuin staattinen lajike, jäsenluokka on instanssikohtainen ja sillä on pääsy kaikkiin ja kaikkiin menetelmiin ja jäseniin, jopa vanhempien Tämä viite.

Paikallinen luokat ilmoitetaan koodilohkossa ja näkyvät vain siinä lohkossa, kuten kaikki muutkin muuttujat.

Lopuksi an tuntematon luokka on paikallinen luokka, jolla ei ole nimeä.

Vastatakseni kysymykseesi keskityn jäseniin ja nimettömiin sisäisiin luokkiin, koska nämä ovat niitä, joita todennäköisesti kohtaat ja käytät. Minulle sisäisten luokkien edut voidaan jakaa kolmeen luokkaan: olio-etu, organisatorinen etu ja takaisinsoitto-etu.

Kohdekohtainen etu

Nöyrä mielestäni sisäisen luokan tärkein piirre on, että sen avulla voit muuttaa asioita esineiksi, joita et tavallisesti muuttaisi esineiksi. Tämä sallii koodisi olla entistä objektiivisempi kuin ilman sisäisiä luokkia.

Katsotaanpa jäsenten luokkaa. Koska sen esiintymä on emoyhteisönsä jäsen, sillä on pääsy kaikkiin vanhemman jäseniin ja menetelmiin. Ensi silmäyksellä tämä ei ehkä näytä paljon; meillä on jo sellainen pääsy vanhempien luokan menetelmän sisällä. Jäsenklassin avulla voimme kuitenkin ottaa logiikan pois vanhemmalta ja objektisoida sen. Esimerkiksi puuluokalla voi olla menetelmä ja monia apumenetelmiä, jotka suorittavat puun etsinnän tai kävelyn. Kohdekeskeisestä näkökulmasta puu on puu, ei hakualgoritmi. Tarvitset kuitenkin läheisen tiedon puun tietorakenteista haun suorittamiseksi.

Sisäisen luokan avulla voimme poistaa kyseisen logiikan ja sijoittaa sen omaan luokkaansa. Joten olio-suuntautuneesta näkökulmasta olemme ottaneet toiminnallisuuden pois siitä, mihin se ei kuulu, ja asettaneet sen omaan luokkaansa. Sisäisen luokan avulla olemme onnistuneesti irrottaneet hakualgoritmin puusta. Nyt voimme muuttaa hakualgoritmia vaihtamalla yksinkertaisesti uuden luokan. Voisin jatkaa, mutta se avaa koodimme monille olio-tekniikoiden tarjoamille eduille.

Organisaation etu

Kohdekeskeinen suunnittelu ei ole kaikkien asia, mutta onneksi sisäiset luokat tarjoavat enemmän. Organisaation näkökulmasta sisäiset luokat antavat meille mahdollisuuden organisoida pakettirakennettamme edelleen käyttämällä nimitiloja. Sen sijaan, että kaikki pakattaisiin tasaiseksi paketiksi, luokat voidaan sisäkkäin luokkiin. Ilman sisäisiä luokkia me rajoittuimme seuraavaan hierarkiarakenteeseen:

paketti1 luokka 1 luokka 2 ... luokka n ... paketti n 

Sisemmillä luokilla voimme tehdä seuraavaa:

paketti 1 luokka 1 luokka 2 luokka 1 luokka 2 ... luokka n 

Varovasti käytettynä sisäiset luokat voivat tarjota rakenteellisen hierarkian, joka sopii luontevammin luokkiin.

Takaisinsoiton etu

Sisäiset jäsenluokat ja nimettömät luokat tarjoavat molemmat kätevän menetelmän soittopyyntöjen määrittelemiseksi. Ilmeisin esimerkki liittyy GUI-koodiin. Soittopyynnön soveltaminen voi kuitenkin ulottua moniin toimialueisiin.

Useimmissa Java-käyttöliittymissä on jonkinlainen komponentti, joka käynnistää actionPerformed () menetelmäpuhelu. Valitettavasti useimmilla kehittäjillä on yksinkertaisesti pääikkunan toteutus ActionListener. Tämän seurauksena kaikki komponentit jakavat saman actionPerformed () menetelmä. Toiminnon suorittavan komponentin selvittämiseksi on yleensä jättiläinen, ruma kytkin actionPerformed () menetelmä.

Tässä on esimerkki monoliittisesta toteutuksesta:

public class SomeGUI laajentaa JFrame-kehystä, toteuttaa ActionListener {suojattu J-painike1; suojattu J-painike2; ... suojattu J-painike N; public void actionPerformed (ActionEvent e) {if (e.getSource () == button1) {// tee jotain} muuta if (e.getSource () == button2) {... saat kuvan 

Aina kun näet kytkimiä tai suuria jos/tai muuten lohkojen, kova hälytyskello pitäisi alkaa soida mielessäsi. Yleensä tällaiset rakenteet ovat huonoja olio-suuntautuneita, koska muutos koodin yhdessä osassa voi edellyttää vastaavaa muutosta kytkinlausekkeessa. Sisäisten jäsenten ja nimettömien luokkien avulla voimme päästä eroon vaihdetuista actionPerformed () menetelmä.

Sen sijaan voimme määritellä sisäisen luokan, joka toteutetaan ActionListener jokaiselle komponentille, jota haluamme kuunnella. Se voi johtaa moniin sisäisiin luokkiin. Voimme kuitenkin välttää suuria kytkinlausekkeita ja saamme lisäbonuksen toimintalogiikkamme kapseloinnista. Lisäksi tämä lähestymistapa voi parantaa suorituskykyä. Kytkimessä, missä niitä on n vertailuja, voimme odottaa n / 2 vertailut keskimääräisessä tapauksessa. Sisäisten luokkien avulla voimme perustaa 1: 1-kirjeenvaihdon toiminnan suorittajan ja toiminnan kuuntelijan välille. Suuressa käyttöliittymässä tällaiset optimoinnit voivat vaikuttaa merkittävästi suorituskykyyn. Nimetön lähestymistapa voi näyttää tältä:

public class SomeGUI laajentaa JFrame {... -painikkeen jäsenilmoituksia ... suojattu void buildGUI () {button1 = new JButton (); painike2 = uusi J-painike (); ... button1.addActionListener (uusi java.awt.event.ActionListener () {public void actionPerformed (java.awt.event.ActionEvent e) {// tee jotain}}); .. toista jokaiselle painikkeelle 

Sisäisten jäsenluokkien avulla sama ohjelma näyttäisi tältä:

julkinen luokka SomeGUI laajentaa JFrame {... -painikkeen jäsenten ilmoitukset // sisäisen luokan määritelmät luokka Button1Handler toteuttaa ActionListener {public void actionPerformed (ActionEvent e) {// tee jotain}} ... määritä jokaiselle painikkeella suojatulle tyhjä buildGUI () {// alustaa painikkeet button1 = new JButton (); painike2 = uusi J-painike (); ... // rekisteröi luokan sisäisen toiminnan kuuntelija-ilmentymä // jokaiselle painikkeelle button1.addActionListener (uusi Button1Handler ()); .. toista jokaiselle painikkeelle 

Koska sisäisillä luokilla on pääsy kaikkeen vanhemmassa, voimme siirtää mitä tahansa logiikkaa, joka olisi esiintynyt monoliittisena actionPerformed () toteutus sisäiseen luokkaan.

Käytän mieluummin jäsenluokat takaisinsoittona. Kyse on kuitenkin henkilökohtaisista mieltymyksistä. Minusta tuntuu vain, että liian monet nimettömät luokat sekoittavat koodia. Minusta tuntuu myös, että nimettömistä luokista voi tulla hankalia, jos ne ovat suurempia kuin yksi tai kaksi riviä.

Haitat?

Kuten kaikessa muussa, on otettava hyvä ja huono. Sisäisillä luokilla on haittansa. Huoltonäkökulmasta kokematon Java-kehittäjä voi löytää sisäisen luokan vaikeata ymmärtää. Sisäisten luokkien käyttö lisää myös koodisi luokkien kokonaismäärää. Lisäksi useimmat Java-työkalut ovat kehityksen näkökulmasta hieman lyhyempiä kuin ne tukevat sisäisiä luokkia. Esimerkiksi päivittäisessä koodauksessa käytän IBM: n VisualAge for Java -sovellusta. Sisäiset luokat kootaan VisualAgessa, mutta sisäistä luokkaa ei ole. Sen sijaan sinun on yksinkertaisesti kirjoitettava sisempi luokka suoraan luokan määritelmään. Se valitettavasti vaikeuttaa sisäisen luokan selaamista. Sitä on myös vaikea kirjoittaa, koska menetät monet VisualAgen koodin täydentämisen apuvälineistä, kun kirjoitat luokan määritelmään tai käytät sisäistä luokkaa.

Tony Sintes on ObjectWaven vanhempi konsultti, erikoistunut televiestintään. Sintes, Sun-sertifioitu Java 1.1 -ohjelmoija ja Java 2 -kehittäjä, on työskennellyt Javan kanssa vuodesta 1997.

Lisätietoja tästä aiheesta

  • Sunin "Inner Class Specification" tarjoaa syvällisen tarkastelun sisäisiin luokkiin

    //java.sun.com/products/jdk/1.1/docs/guide/innerclasses/spec/innerclasses.doc.html

Tämän tarinan, "Sisäkurssit", julkaisi alun perin JavaWorld.

$config[zx-auto] not found$config[zx-overlay] not found