Programiranje

Notranji razredi

V: Za kaj so torej notranji razredi sploh dobri?

A: Notranji razredi gnezdijo v drugih razredih. Običajni razred je neposredni član paketa, razred najvišje stopnje. Notranji razredi, ki so postali na voljo z Javo 1.1, so na voljo v štirih različicah:

  • Statični razredi članov
  • Članski razredi
  • Lokalni razredi
  • Anonimni razredi

Na hitro si oglejmo vsakega po vrsti.

Na kratko, a statični članski razred je statični član razreda. Tako kot katera koli druga statična metoda ima tudi statični član član dostop do vseh statičnih metod nadrejenega ali najvišjega razreda.

Kot statični članski razred, a članski razred je opredeljen tudi kot član predavanja. Za razliko od statične sorte je članski razred specifičen in ima dostop do vseh in vseh metod in članov, tudi nadrejenega to sklic.

Lokalno razredi so navedeni v bloku kode in so vidni samo znotraj tega bloka, tako kot katera koli druga spremenljivka metode.

Končno, anonimno class je lokalni razred, ki nima imena.

Če želite odgovoriti na vaše specifično vprašanje, se bom osredotočil na članske in anonimne notranje tečaje, saj so to tisti, s katerimi se boste verjetno srečali in jih uporabljali. Zame prednosti notranjega razreda lahko razdelimo v tri kategorije: objektno usmerjena prednost, organizacijska prednost in prednost povratnega klica.

Predmetno usmerjena prednost

Po mojem skromnem mnenju je najpomembnejša značilnost notranjega razreda ta, da vam omogoča, da stvari spremenite v predmete, ki jih običajno ne bi spremenili v predmete. To omogoča, da je vaša koda še bolj objektno usmerjena, kot bi bila brez notranjih razredov.

Poglejmo članski razred. Ker je njegov primerek član nadrejenega primerka, ima dostop do vseh članov in metod v nadrejenem primeru. Na prvi pogled se to morda ne zdi veliko; takšen dostop že imamo znotraj metode v nadrejenem razredu. Vendar nam članski razred omogoča, da vzamemo logiko iz starša in jo objektiviziramo. Na primer, drevesni razred ima lahko metodo in številne pomožne metode, ki izvajajo iskanje ali sprehod po drevesu. Z objektno usmerjenega vidika je drevo drevo in ne algoritem iskanja. Za iskanje potrebujete natančno znanje o drevesnih podatkovnih strukturah.

Notranji razred nam omogoča, da odstranimo to logiko in jo umestimo v svoj razred. Torej s objektno usmerjenega vidika smo funkcionalnost odvzeli tja, kamor ne sodi, in jo postavili v svoj razred. Z uporabo notranjega razreda smo algoritem iskanja uspešno ločili od drevesa. Zdaj lahko za spremembo algoritma iskanja preprosto zamenjamo nov razred. Lahko bi nadaljeval, vendar to odpira našo kodo za številne prednosti, ki jih nudijo objektno usmerjene tehnike.

Organizacijska prednost

Predmetno oblikovanje ni stvar vsakogar, a na srečo notranji razredi ponujajo več. Z organizacijskega vidika nam notranji razredi omogočajo nadaljnjo organizacijo strukture paketa z uporabo imenskih prostorov. Namesto da bi vse razvrstili v ploščati paket, lahko razrede še naprej ugnezdimo v razrede. Izrecno smo bili brez notranjih razredov omejeni na naslednjo hierarhično strukturo:

paket1 razred 1 razred 2 ... razred n ... paket n 

Z notranjimi razredi lahko naredimo naslednje:

paket 1 razred 1 razred 2 razred 1 razred 2 ... razred n 

Notranji razredi s skrbno uporabo lahko zagotovijo strukturno hierarhijo, ki bolj ustreza vašim razredom.

Prednost povratnega klica

Razredi notranjih članov in anonimni razredi ponujajo priročen način za določanje povratnih klicev. Najbolj očiten primer se nanaša na kodo GUI. Uporaba povratnega klica pa se lahko razširi na številne domene.

Večina grafičnih uporabniških vmesnikov Java ima nekakšno komponento, ki spodbuja actionPerformed () klic metode. Na žalost ima večina razvijalcev preprosto glavno okno ActionListener. Posledično imajo vse komponente enako actionPerformed () metoda. Da bi ugotovili, katera komponenta je izvedla dejanje, je običajno v velikanskem, grdem stikalu actionPerformed () metoda.

Tu je primer monolitne izvedbe:

javni razred SomeGUI razširja JFrame implementira ActionListener {zaščiten gumb JButton1; zaščiten gumb JButton2; ... zaščiten gumb JButtonN; public void actionPerformed (ActionEvent e) {if (e.getSource () == button1) {// naredite nekaj} drugače, če (e.getSource () == button2) {... dobite sliko 

Kadar koli vidite stikala ali velika če/če potem bloki, naj bi v vaših mislih začeli zvoniti glasni alarmni zvonovi. Na splošno so takšni konstrukti slaba objektno usmerjena zasnova, saj lahko sprememba enega odseka kode zahteva ustrezno spremembo stavka switch. Razredi notranjih članov in anonimni razredi nam omogočajo, da se odmaknemo od preklopljenega actionPerformed () metoda.

Namesto tega lahko definiramo notranji razred, ki izvaja ActionListener za vsako komponento, ki jo želimo poslušati. To lahko povzroči številne notranje razrede. Vendar se lahko izognemo velikim izjavam o preklopih in imamo dodaten dodatek, da vključimo svojo akcijsko logiko. Poleg tega lahko ta pristop izboljša učinkovitost. V stikalu, kjer so n lahko pričakujemo primerjave n / 2 primerjave v povprečnem primeru. Notranji razredi nam omogočajo, da vzpostavimo korespondenco 1: 1 med izvajalcem in poslušalcem. V velikem grafičnem uporabniškem vmesniku lahko takšne optimizacije bistveno vplivajo na zmogljivost. Anonimni pristop je lahko videti takole:

javni razred SomeGUI razširja JFrame {... izjave članov gumba ... zaščitena praznina buildGUI () {button1 = new JButton (); button2 = nov JButton (); ... button1.addActionListener (new java.awt.event.ActionListener () {public void actionPerformed (java.awt.event.ActionEvent e) {// naredi nekaj}}); .. ponovite za vsak gumb 

Z uporabo razredov notranjih članov bi bil isti program videti takole:

javni razred SomeGUI razširja JFrame {... izjave članov gumba // definicije notranjega razreda razred Button1Handler implementira ActionListener {public void actionPerformed (ActionEvent e) {// naredi nekaj}} ... definirajte razred notranjega člana za vsak gumb zaščiten void buildGUI () {// inicializirajte gumbe button1 = new JButton (); button2 = nov JButton (); ... // registriramo primerek poslušalca dejanj v notranjem razredu // za vsak gumb button1.addActionListener (nov Button1Handler ()); .. ponovite za vsak gumb 

Ker imajo notranji razredi dostop do vsega v staršu, lahko premikamo katero koli logiko, ki bi se pojavila monolitno actionPerformed () izvedba v notranji razred.

Članske razrede raje uporabljam kot povratne klice. Vendar je to stvar osebnih želja. Preprosto čutim, da preveč anonimnih razredov nered kodira. Prav tako menim, da lahko anonimni razredi postanejo okorni, če so daljši od ene ali dveh vrstic.

Slabosti?

Kot pri vsem drugem je treba tudi dobrega sprejeti za slabega. Notranji razredi imajo svoje slabosti. Z vidika vzdrževanja bodo neizkušeni razvijalci Java težko razumeli notranji razred. Uporaba notranjih razredov bo povečala tudi skupno število razredov v vaši kodi. Poleg tega se z razvojnega vidika večina orodij Java nekoliko izogiba podpori notranjim razredom. Na primer, za vsakodnevno kodiranje uporabljam IBM-ov VisualAge for Java. Medtem ko bodo notranji razredi prevedeni v VisualAge, ne obstaja noben brskalnik ali predloga notranjega razreda. Namesto tega morate preprosto vtipkati notranji razred neposredno v definicijo razreda. To žal otežuje brskanje po notranjem razredu. Težko je tudi tipkati, saj izgubite veliko pripomočkov za dokončanje kode VisualAge, ko vtipkate definicijo razreda ali uporabite notranji razred.

Tony Sintes je višji svetovalec pri ObjectWave, specializiran za telekomunikacije. Sintes, programer Java 1.1 in razvijalec Java 2 s certifikatom Sun, z Javo sodeluje od leta 1997.

Preberite več o tej temi

  • "Specifikacija notranjih razredov" podjetja Sun ponuja poglobljen vpogled v notranje razrede

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

To zgodbo, "Notranji razredi", je prvotno objavil JavaWorld.

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