Programmering

Java 101: Pakker organiserer klasser og grensesnitt

Hvorfor gjenoppfinne hjulet? Denne klisjeen gjelder programvareutvikling der noen utviklere ofte skriver om den samme koden for forskjellige programmer. To ulemper med den tilnærmingen er:

  1. Det kaster bort tid
  2. Det introduserer potensialet for feil i feilsøkt kode

Som et alternativ til omskriving av samme kode, gir mange programvareutviklingsmiljøer et biblioteksverktøy som organiserer ofte brukt kode. Når utviklere er ferdig med feilsøking av en gjenbrukbar kode, bruker de verktøyet til å lagre den koden i en bibliotek—En eller flere filer som inneholder ofte brukt kode for bruk i forskjellige programmer. Under programbygging får kompilatoren eller biblioteksverktøyet tilgang til biblioteket for å koble programmets bibliotekhenviste kode til programmet.

Biblioteker er grunnleggende for Java. De tillater delvis JVMs klasselaster å finne klassefiler. (Jeg vil utforske klasselastere i en fremtidig artikkel.) Av den grunn er Java's biblioteker ofte kjent som klassebiblioteker. Imidlertid refererer Java til klassebiblioteker som pakker.

Denne artikkelen utforsker pakker; Jeg viser deg hvordan du lager pakker med klasser og grensesnitt, hvordan du importerer (det vil si bringe inn i et program) pakkede klasser og grensesnitt, hvordan du flytter pakker på harddisken, og hvordan du bruker jar-filer til å kapsle inn pakker.

Merk
Denne artikkelens enkeltpakkeeksperiment er Microsoft Windows-spesifikt. Du burde være i stand til enkelt å ekstrapolere dette eksperimentet til ikke-Windows-plattformer.

Hva er pakker?

EN pakke er en samling av klasser og grensesnitt. Hver pakke har sitt eget navn og organiserer klassene og grensesnittene på toppnivå (dvs. ikke-nestede) i et eget navneområde, eller navnesamling. Selv om samme navngitte klasser og grensesnitt ikke kan vises i samme pakke, kan de vises i forskjellige pakker fordi et eget navneområde tildeles hver pakke.

Fra et implementeringsperspektiv viser det seg nyttig å sidestille en pakke med en katalog, og det samme som å ligne en pakkes klasser og grensesnitt med klassefilene til en katalog. Husk andre tilnærminger - for eksempel bruk av databaser - for å implementere pakker, så ikke vær vane med å alltid sidestille pakker med kataloger. Men fordi mange JVM-er bruker kataloger for å implementere pakker, tilsvarer denne artikkelen pakker med kataloger. Java 2 SDK organiserer sin enorme samling av klasser og grensesnitt i et trelignende hierarki av pakker i pakker, som tilsvarer kataloger i kataloger. Dette hierarkiet gjør at Sun Microsystems enkelt kan distribuere (og du enkelt arbeide med) disse klassene og grensesnittene. Eksempler på Java-pakker inkluderer:

  • java.lang: En samling av språkrelaterte klasser, som f.eks Gjenstand og String, organisert i java pakken er lang underpakke
  • java.lang.ref: En samling referanserelaterte språkkurs, for eksempel SoftReference og ReferenceQueue, organisert i ref del-underpakning av java pakken er lang underpakke
  • javax.swing: En samling av Swing-relaterte komponentklasser, for eksempel JButton, og grensesnitt, for eksempel ButtonModel, organisert i javax pakken er svinge underpakke

Periodekarakterer skiller pakkenavn. For eksempel i javax.swing, et periodetegn skiller pakkenavnet javax fra underpakkenavn svinge. En periodekarakter er den plattformuavhengige ekvivalenten av skråstrek-tegn (/), tilbakeslagstegn (\), eller andre tegn for å skille katalognavn i en katalogbasert pakkeimplementering, databasegrener i en hierarkisk databasebasert pakkeimplementering, og så videre.

Tips
Akkurat som du ikke kan lagre både en fil og en katalog med identiske navn i samme katalog, kan du ikke lagre en klasse eller et grensesnitt og en pakke med identiske navn i samme pakke. For eksempel gitt en pakke som heter kontoer, kan du ikke lagre både en pakke og en klasse som heter som skal betales i kontoer. For å unngå motstridende navn, store bokstaver i klasse- og grensesnittnavn, og små bokstaver i pakkenavn. Ved hjelp av forrige eksempel, butikklasse Som skal betales i pakke kontoer som kontoer. betales og pakke som skal betales i pakke kontoer som kontoer. betalbar. Lær mer om dette og andre navnekonvensjoner fra Suns Kodekonvensjoner for Java-programmeringsspråket.

Lag en pakke med klasser og grensesnitt

Hver kildefils klasser og grensesnitt organiseres i en pakke. I pakke direktivets fravær, de klassene og grensesnittene tilhører den ikke-navngitte pakken (katalogen JVM anser som den nåværende katalogen - katalogen der et Java-program begynner å kjøre det via Windows java.exe, eller OS-ekvivalent, program — og inneholder ingen underpakker). Men hvis den pakke direktivet vises i en kildefil, det direktivet navngir pakken for disse klassene og grensesnittene. Bruk følgende syntaks til å spesifisere en pakke direktiv i kildekode:

'pakke' packageName [ '.' underpakkenavn ... ] ';' 

EN pakke direktivet begynner med pakke nøkkelord. En identifikator som navngir en pakke, packageName, følger umiddelbart. Hvis klasser og grensesnitt skal vises i en underpakke (på et eller annet nivå) innenfor packageName, en eller flere periodeseparerte underpakkenavn identifikatorer vises etter packageName. Følgende kodefragment presenterer et par pakke direktiver:

pakke spill; pakke spill. enheter; 

Den første pakke direktivet identifiserer en pakke som heter spill. Alle klasser og grensesnitt som vises i direktivets kildefil, organiseres i spill pakke. Den andre pakke direktivet identifiserer en navngitt delpakke enheter, som ligger i en pakke som heter spill. Alle klasser og grensesnitt som vises i direktivets kildefil, organiseres i spill pakken er enheter underpakke. Hvis en JVM-implementering tilordner pakkenavn til katalognavn, spill. enheter kart til en spill \ enheter kataloghierarki under Windows og a spill / enheter kataloghierarki under Linux eller Solaris.

Forsiktighet
Bare en pakke direktivet kan vises i en kildefil. Videre er den pakke direktivet må være den første koden (bortsett fra kommentarer) i den filen. Brudd på en av reglene får Java-kompilatoren til å rapportere en feil.

For å hjelpe deg med å bli komfortabel med pakker, har jeg utarbeidet et eksempel som spenner over alle emnene i denne artikkelen. I denne delen lærer du hvordan du lager eksemplets pakke. I senere seksjoner vil du lære hvordan du importerer en klasse og et grensesnitt fra denne pakken, hvordan du flytter denne pakken til et annet sted på harddisken og fremdeles får tilgang til pakken fra et program, og hvordan du lagrer pakken i en jar-fil . Oppføring 1 presenterer pakkens kildekode:

Oppføring 1. A.java

// A.java-pakke testpkg; offentlig klasse A {int x = 1; offentlig int y = 2; beskyttet int z = 3; int returnx () {return x; } public int returny () {return y; } beskyttet int returnz () {return z; } offentlig grensesnitt StartStop {ugyldig start (); ugyldig stopp (); }} klasse B {offentlig statisk tomrom hallo () {System.out.println ("hei"); }} 

Oppføring 1 introduserer kildekoden til den først navngitte pakken. De pakke testpkg; direktivet navngir den pakken testpkg. Innenfor testpkg er klasser EN og B. Innenfor EN er tre feltdeklarasjoner, tre metodedeklarasjoner og en indre grensesnitterklæring. Innenfor B er en enkeltmetodedeklarasjon. Hele kildekoden lagres i A.java fordi EN er en offentlig klasse. Vår oppgave: Gjør denne kildekoden til en pakke som består av to klasser og et indre grensesnitt (eller en katalog som inneholder tre klassefiler). Følgende Windows-spesifikke trinn utfører den oppgaven:

  1. Åpne et Windows-kommandovindu og sørg for at du er i c: stasjonens rotkatalog (hovedkatalogen — representert med et innledende tilbakeslag\) karakter). For å gjøre det, skriv inn c: kommando etterfulgt av cd \ kommando. (Hvis du bruker en annen stasjon, bytt ut c: med den valgte stasjonen. Ikke glem å trykke Enter når du har skrevet en kommando.)
  2. Lage en testpkg katalog ved å skrive md testpkg. Merk: Når du følger trinnene i denne artikkelen, må du ikke skrive perioder etter kommandoene.
  3. Gjøre testpkg gjeldende katalog ved å skrive cd testpkg.
  4. Bruk en redaktør til å angi Listing 1's kildekode og lagre den koden til en A.java fil i testpkg.
  5. Kompilere A.java ved å skrive javac A.java. Du bør se klassefiler En $ StartStop.-klasse, En klasse, og B. klasse vises i testpkg katalog.

Figur 1 illustrerer trinn 3 til 5.

Gratulerer! Du har nettopp laget din første pakke. Tenk på denne pakken som inneholder to klasser (EN og B) og ENsitt eneste indre grensesnitt (Start stopp). Du kan også tenke på denne pakken som en katalog som inneholder tre klassefiler: En $ StartStop.-klasse, En klasse, og B. klasse.

Merk
For å minimere pakkenavnekonflikter (spesielt blant kommersielle pakker) har Sun etablert en konvensjon der selskapets Internett-domenenavn reverserer og prefikser et pakkenavn. For eksempel et selskap med x.com som internett-domenenavn og a.b som et pakkenavn (en) etterfulgt av et underpakkenavn (b) prefikser com.x til a.b, resulterer i com.x.a.b. Artikkelen min følger ikke denne konvensjonen fordi testpkg pakken er kun kastet designet for undervisningsformål.

Importer klasser og grensesnitt for en pakke

Når du har en pakke, vil du importere klasser og / eller grensesnitt - faktisk navn på klasse og / eller grensesnitt - fra den pakken til programmet ditt, slik at det kan bruke disse klassene og / eller grensesnittene. En måte å utføre denne oppgaven på er å oppgi det fullstendige pakkenavnet (pakkenavnet og alle underpakkenavn) på hvert sted der referansetypenavnet (klassen eller grensesnittnavnet) vises, som oppføring 2 viser:

Oppføring 2. Usetestpkg1.java

// Usetestpkg1.java klasse Usetestpkg1 implementerer testpkg.A.StartStop {public static void main (String [] args) {testpkg.A a = new testpkg.A (); System.out.println (a.y); System.out.println (a.returny ()); Usetestpkg1 utp = ny Usetestpkg1 (); utp.start (); utp.stop (); } offentlig ugyldig start () {System.out.println ("Start"); } offentlig ugyldig stopp () {System.out.println ("Stopp"); }} 

Ved å prefikse testpkg. til EN, Usetestpkg1 tilgang testpkgsin klasse EN to steder og ENsitt indre grensesnitt Start stopp på en plass. Fullfør følgende trinn for å kompilere og kjøre Usetestpkg1:

  1. Åpne et Windows-kommandovindu og sørg for at du er i c: stasjonens rotkatalog.
  2. Sørg for at klassesti miljøvariabel eksisterer ikke ved å utføre angi klassebane =. (Jeg diskuterer klassesti senere i denne artikkelen.)
  3. Bruk en redaktør til å angi kildekoden til Listing 2 og lagre den koden i en Usetestpkg1.java filen i rotkatalogen.
  4. Kompilere Usetestpkg1.java ved å skrive javac Usetestpkg1.java. Du bør se klassefilen Usetestpkg1.klasse vises i rotkatalogen.
  5. Type java Usetestpkg1 for å kjøre dette programmet.

Figur 2 illustrerer trinn 3 til 5 og viser programmets produksjon.

I følge Usetestpkg1sin produksjon, den hoved() metoden tråd har tilgang til testpkg.As y felt og kaller retur () metode. Videre viser produksjonen en vellykket implementering av testpkg.A.StartStop indre grensesnitt.

Til Usetestpkg1, prefiks testpkg. til EN tre steder virker det ikke så veldig. Men hvem vil spesifisere et fullt kvalifisert pakkenavnsprefiks hundre steder? Heldigvis leverer Java import direktivet om å importere pakkens offentlige referansetypenavn (er), slik at du ikke trenger å oppgi fullstendige prefiks for pakkenavn. Uttrykk en import direktiv i kildekode via følgende syntaks:

'import' packageName [ '.' underpakkenavn ... ] '.' ( referansetypenavn | '*' ) ';' 

An import direktivet består av import nøkkelord umiddelbart etterfulgt av en identifikator som navngir en pakke, packageName. En valgfri liste over underpakkenavn identifikatorer følger for å identifisere riktig underpakning (om nødvendig). Direktivet avsluttes med enten a referansetypenavn identifikator som identifiserer en bestemt klasse eller et grensesnitt fra pakken, eller en stjerne (*) karakter. Hvis referansetypenavn vises, er direktivet en enkelttype import direktivet. Hvis det vises en stjerne, er direktivet et type-on-demand import direktivet.

Forsiktighet
Som med pakke direktiv, import direktiver må vises foran enhver annen kode, med tre unntak: a pakke direktiv, annet import direktiver, eller kommentarer.

Den eneste typen import direktiv importerer navnet på en enkelt offentlig referansetype fra en pakke, som følgende kodefragment viser:

importere java.util.Date; 

Den forrige single-typen import direktiv importerer klassenavn Dato inn i kildekoden. Som et resultat spesifiserer du Dato i stedet for java.util.Date hvert sted vises kursnavnet i kildekoden. For eksempel når du oppretter en Dato objekt, spesifiser Dato d = ny Dato (); i stedet for java.util.Date d = ny java.util.Date ();.

Utvis forsiktighet med en type import direktiver. Hvis kompilatoren oppdager en enkelt type import direktiv som spesifiserer et referansetypenavn som også er deklarert i en kildefil, rapporterer kompilatoren en feil, som følgende kodefragment viser:

importere java.util.Date; klasse Dato {} 

Kompilatoren ser på kodefragmentet som et forsøk på å introdusere to referansetyper med det samme Dato Navn:

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