Mano ankstesniame „Java 101“ pamoka, jūs sužinojote, kaip geriau tvarkyti kodą, deklaruodami nuorodų tipus (dar vadinamus klasėmis ir sąsajomis) kitų nuorodų tipų ir blokų nariais. Aš taip pat parodžiau, kaip naudoti lizdą, kad būtų išvengta vardų konfliktų tarp įdėtų nuorodų tipų ir aukščiausio lygio nuorodų tipų, kurie turi tą patį pavadinimą.
Kartu su lizdu „Java“ naudoja paketus, kad išspręstų to paties pavadinimo problemas aukščiausio lygio nuorodų tipuose. Statinio importavimo naudojimas taip pat supaprastina prieigą prie statinių narių supakuotuose aukščiausio lygio nuorodų tipuose. Statinis importavimas sutaupys klavišų paspaudimus, kai prieisite prie šių savo kodo narių, tačiau juos naudojant reikia atkreipti dėmesį į keletą dalykų. Šioje pamokoje aš supažindinsiu jus su paketų naudojimu ir statiniu importavimu savo „Java“ programose.
atsisiųsti Gauti kodą Atsisiųskite šaltinių kodą, pvz., programas, šioje „Java“ mokymo programoje. Sukūrė Jeffas Friesenas, skirtas „JavaWorld“.Pakuotės nuorodų tipai
„Java“ kūrėjai grupuoja susijusias klases ir sąsajas į paketus. Naudojant paketus lengviau rasti ir naudoti nuorodų tipus, išvengti vardų konfliktų tarp tų pačių pavadinimų tipų ir kontroliuoti prieigą prie tipų.
Šiame skyriuje sužinosite apie paketus. Sužinosite, kokie yra paketai, sužinosite apie pakuotė
ir importas
sakinius ir nagrinėkite papildomas apsaugotos prieigos, JAR failų ir tipų paieškų temas.
Kas yra „Java“ paketai?
Kurdami programinę įrangą, mes paprastai organizuojame elementus pagal jų hierarchinius santykius. Pavyzdžiui, ankstesnėje pamokoje aš jums parodžiau, kaip deklaruoti klases kaip kitų klasių narius. Mes taip pat galime naudoti failų sistemas, kad įdėtume katalogus į kitus katalogus.
Naudodami šias hierarchines struktūras galėsite išvengti vardų konfliktų. Pavyzdžiui, ne hierarchinėje failų sistemoje (viename kataloge) neįmanoma to paties pavadinimo priskirti keliems failams. Priešingai, hierarchinė failų sistema leidžia tų pačių pavadinimų failus egzistuoti skirtinguose kataloguose. Panašiai dviejose uždarosiose klasėse gali būti to paties pavadinimo įdėtos klasės. Vardų konfliktų nėra, nes elementai yra suskirstyti į skirtingas vardų sritis.
„Java“ taip pat leidžia mums suskirstyti aukščiausio lygio (ne įdėtus) nuorodų tipus į kelias vardų sritis, kad galėtume geriau sutvarkyti šiuos tipus ir užkirsti kelią vardų konfliktams. „Java“ paketo kalbos funkciją naudojame viršutinio lygio nuorodų tipų skaidymui į kelias vardų sritis. Šiuo atveju a pakuotė yra unikali vardų sritis, skirta saugoti nuorodų tipus. Paketai gali laikyti klases ir sąsajas, taip pat paketai, kurios yra pakuotės, įdėtos į kitas pakuotes.
Paketas turi pavadinimą, kuris turi būti nerezervuotas identifikatorius; pavyzdžiui, java
. Narių prieigos operatorius (.
) atskiria paketo pavadinimą nuo paketo pavadinimo ir atskiria paketo ar paketo pavadinimą nuo tipo pavadinimo. Pavyzdžiui, dviejų narių prieigos operatoriai java.lang.Sistema
atskiras paketo pavadinimas java
nuo lang
pakuotės pavadinimas ir atskiras pakuotės pavadinimas lang
nuo Sistema
tipo pavadinimas.
Turi būti deklaruojami pagrindiniai tipai visuomenės
kad būtų galima patekti iš jų pakuočių išorės. Tas pats pasakytina apie visas konstantas, konstruktorius, metodus ar įdėtus tipus, kurie turi būti prieinami. Šių pavyzdžių pamatysite vėliau pamokoje.
Paketo išrašas
„Java“ mes naudojame paketo išrašas sukurti paketą. Šis sakinys rodomas šaltinio failo viršuje ir identifikuoja paketą, kuriam priklauso šaltinio failų tipai. Ji turi atitikti šią sintaksę:
pakuotė identifikatorius[.identifikatorius]*;
Paketo sakinys prasideda rezervuotu žodžiu pakuotė
ir tęsiama identifikatoriumi, po kurio pasirinktinai seka taškų atskirtoji identifikatorių seka. Kabliataškis (;
) nutraukia šį teiginį.
Pirmasis (kairysis kairysis) identifikatorius pavadina paketą, o kiekvienas paskesnis identifikatorius - paketą. Pavyzdžiui, paketas a.b;
, visi šaltinio faile deklaruoti tipai priklauso b
subpakuotė a
pakuotė.
Pakuočių / pakuočių pavadinimų suteikimo tvarka
Pagal susitarimą pakuotės ar pakuotės pavadinimą išreiškiame mažosiomis raidėmis. Kai vardą sudaro keli žodžiai, kiekvieną žodį galite rašyti didžiąja raide, išskyrus pirmąjį; pavyzdžiui, didžioji knyga
.
Paketų pavadinimų seka turi būti unikali, kad būtų išvengta kompiliavimo problemų. Pavyzdžiui, tarkime, kad sukūrėte du skirtingus grafika
paketus, ir manykite, kad kiekvienas grafika
pakuotėje yra a Trikampis
klasės su kita sąsaja. Kai „Java“ kompiliatorius susiduria su kažkuo panašiu į tai, kas yra žemiau, jis turi patikrinti, ar Trikampis (int, int, int, int)
konstruktorius egzistuoja:
Trikampis t = naujas trikampis (1, 20, 30, 40);
Trikampį ribojanti dėžutė
Pagalvokite apie Trikampis
konstruktorius kaip nurodantis ribojančią dėžę, kurioje nupiešiamas trikampis. Pirmieji du parametrai nurodo langelio viršutinį kairįjį kampą, o antrieji du parametrai nurodo langelio apimtį.
Kompiliatorius ieškos visų prieinamų paketų, kol ras grafika
pakuotė, kurioje yra a Trikampis
klasė. Jei rastame pakete yra atitinkama Trikampis
klasė su a Trikampis (int, int, int, int)
konstruktorius, viskas gerai. Priešingu atveju, jei rasta Trikampis
klasėje nėra a Trikampis (int, int, int, int)
konstruktorius, kompiliatorius praneša apie klaidą. (Apie paieškos algoritmą pasakysiu vėliau šioje pamokoje.)
Šis scenarijus parodo, kaip svarbu pasirinkti unikalias paketų pavadinimų sekas. Pasirenkant unikalią vardų seką įprasta pakeisti savo interneto domeno vardą ir naudoti jį kaip sekos priešdėlį. Pavyzdžiui, aš rinkčiausi ca.javajeffas
kaip mano priešdėlis, nes javajeff.ca
yra mano domeno vardas. Tada patikslinčiau ca.javajeff.graphics.Triangle
prieiti Trikampis
.
Domeno vardo komponentai ir galiojantys paketų pavadinimai
Domeno vardo komponentai ne visada yra tinkami paketų pavadinimai. Vienas ar daugiau komponentų pavadinimų gali prasidėti skaitmeniu (3D.com
), turi brūkšnį (-
) ar kito neteisėto pobūdžio asmens (ab-z.com
) arba būti vienas iš „Java“ rezervuotų žodžių (short.com
). „Convention“ nurodo, kad prieš skaitmenį prieš pabraukdami (com._3D
), neteisėtą simbolį pakeiskite pabraukimu (com.ab_z
) ir pridėkite rezervuotą žodį pabraukimu (com.trumpa_
).
Turite laikytis kelių taisyklių, kad išvengtumėte papildomų problemų dėl paketo išrašo:
- Šaltinio faile galite deklaruoti tik vieną paketo pareiškimą.
- Negalite prieš paketo pareiškimą rašyti nieko, išskyrus komentarus.
Pirmoji taisyklė, kuri yra specialus antrosios taisyklės atvejis, egzistuoja, nes nėra prasmės laikyti nuorodos tipą keliuose paketuose. Nors pakuotėje gali būti saugomi keli tipai, tipas gali priklausyti tik vienam paketui.
Kai šaltinio failas nedeklaruoja paketo sakinio, sakoma, kad šaltinio failo tipai priklauso neįvardinta pakuotė. Netrivialūs nuorodų tipai paprastai laikomi atskirose pakuotėse ir vengia neįvardyto paketo.
„Java“ diegimai paketų ir paketų pavadinimus susieja su tų pačių pavadinimų katalogais. Pavyzdžiui, įgyvendinimas atvaizduotų grafika
į katalogą pavadinimu grafika
. Pakuotės atveju a.b
, pirmoji raidė, a susieti su katalogu, pavadintu a
ir b atvaizduotų a b
pakatalogis a
. Kompiliatorius saugo klasės failus, kurie įgyvendina paketo tipus, atitinkamame kataloge. Atkreipkite dėmesį, kad neįvardytas paketas atitinka dabartinį katalogą.
Pavyzdys: Garso bibliotekos pakavimas į „Java“
Praktinis pavyzdys yra naudingas norint visiškai suvokti pakuotė
pareiškimas. Šiame skyriuje demonstruoju paketus garso bibliotekos kontekste, leidžiančiame skaityti garso failus ir gauti garso duomenis. Dėl trumpumo pateiksiu tik karkasinę bibliotekos versiją.
Šiuo metu garso biblioteką sudaro tik dvi klasės: Garsas
ir „WavReader“
. Garsas
apibūdina garso įrašą ir yra pagrindinė bibliotekos klasė. 1 sąraše pateikiamas jo šaltinio kodas.
Sąrašas 1. Paketo išrašo pavyzdys (Audio.java)
paketas ca.javajeff.audio; public final class Audio {private int [] pavyzdžiai; private int sampleRate; Garso įrašas (int [] pavyzdžiai, int sampleRate) {this.samples = pavyzdžiai; this.sampleRate = sampleRate; } public int [] getSamples () {grąžinti pavyzdžius; } public int getSampleRate () {return sampleRate; } public static Audio newAudio (String filename) {if (filename.toLowerCase (). endWith (". wav")) grąžinti WavReader.read (failo vardas); else return null; // nepalaikomas formatas}}
Peržiūrėkime 1 sąrašą po žingsnio.
-
Audio.java
1 sąrašo failas saugoGarsas
klasė. Šis sąrašas prasideda paketo sakiniu, kuris identifikuojaca.javajeff.audio
kaip klasės paketas. Garsas
yra deklaruojamasvisuomenės
kad į jį būtų galima kreiptis iš jo pakuotės ribų. Be to, tai deklaruotagalutinis
kad jo nebūtų galima išplėsti (turint omenyje subklasę).Garsas
pareiškiaprivatus
pavyzdžiai
irsampleRate
laukai garso duomenims saugoti. Šie laukai inicijuojami pagal perduotas vertesGarsas
konstruktorius.Garsas
deklaruojamas konstruktorius paketas-privatus (tai reiškia, kad konstruktorius nėra deklaruojamasvisuomenės
,privatus
arbasaugomi
), kad šios klasės nebūtų galima nustatyti tiesiai iš jos paketo ribų.Garsas
dovanos„getSamples“ ()
irgetSampleRate ()
garso įrašo pavyzdžių grąžinimo būdai ir atrankos dažnis. Kiekvienas metodas yra deklaruojamasvisuomenės
kad jį būtų galima iškviesti iš išorėsGarsas
paketą.Garsas
baigia avisuomenės
irstatinis
newAudio ()
gamyklos metodas grąžintiGarsas
objektas, atitinkantisfailo pavadinimas
argumentas. Jei garso įrašo nepavyksta gauti,niekinis
yra grąžinamas.newAudio ()
lyginafailo pavadinimas
pratęsimas su.wav
(šis pavyzdys palaiko tik WAV garsą). Jei jie sutampa, jis vykdomasgrąžinti WavReader.read (failo pavadinimas)
grąžintiGarsas
objektas su WAV pagrįstais garso duomenimis.
2 sąraše aprašoma „WavReader“
.
2 sąrašas. „WavReader“ pagalbininkų klasė (WavReader.java)
paketas ca.javajeff.audio; final class WavReader {static Audio read (String filename) {// Perskaitykite failo pavadinimo failo turinį ir apdorokite jį // į pavyzdžių reikšmių masyvą ir mėginių dažnio // reikšmę. Jei failo nuskaityti negalima, grąžinkite nulį. Dėl // trumpumo (ir kadangi aš dar neaptariau „Java“ // failų įvesties / išvesties API), pateikiu tik griaučių kodą, kuris // visada pateikia garso objektą su numatytosiomis reikšmėmis. grąžinti naują garso įrašą (naujas int [0], 0); }}
„WavReader“
skirtas skaityti WAV failo turinį į Garsas
objektas. (Galiausiai klasė bus didesnė su papildomais privatus
laukai ir metodai.) Atkreipkite dėmesį, kad ši klasė nėra deklaruota visuomenės
, kuris padaro „WavReader“
prieinama Garsas
bet ne koduoti už ca.javajeff.audio
pakuotė. Galvoti apie „WavReader“
kaip pagalbininkų klasė, kurios vienintelė egzistavimo priežastis yra tarnauti Garsas
.
Norėdami sukurti šią biblioteką, atlikite šiuos veiksmus:
- Pasirinkite tinkamą failų sistemos vietą kaip dabartinį katalogą.
- Sukurti
ca / javajeff / audio
pakatalogių hierarchija dabartiniame kataloge. - Nukopijuokite 1 ir 2 sąrašus į failus
Audio.java
irWavReader.java
atitinkamai; ir išsaugokite šiuos failusgarso
pakatalogis. - Darant prielaidą, kad dabartiniame kataloge yra
apie
pakatalogį, vykdytijavac ca / javajeff / audio / *. java
surinkti du šaltinio failus įca / javajeff / audio
. Jei viskas gerai, turėtumėte atrastiGarso.klasė
ir„WavReader.class“
failusgarso
pakatalogis. (Arba šiame pavyzdyje galite pereiti priegarso
pakatalogį ir vykdytijavac * .java
.)
Dabar, sukūrę garso biblioteką, norėsite ja naudotis. Netrukus pažvelgsime į mažą „Java“ programą, kuri demonstruoja šią biblioteką. Pirmiausia turite sužinoti apie importo ataskaitą.
„Java“ importo ataskaita
Įsivaizduokite, kad turite nurodyti ca.javajeff.graphics.Triangle
kiekvienam įvykiui Trikampis
šaltinio kode, pakartotinai. „Java“ pateikia importo ataskaitą kaip patogią alternatyvą praleisti ilgą paketo informaciją.
Importo pareiškime importuojami tipai iš paketo nurodant kompiliatoriui, kur ieškoti nekvalifikuotas (be paketo priešdėlio) tipo pavadinimai kompiliavimo metu. Jis rodomas šalia šaltinio failo viršaus ir turi atitikti šią sintaksę:
importas identifikatorius[.identifikatorius]*.(typeName | *);
Importavimo ataskaita prasideda rezervuotu žodžiu importas
ir tęsiamas identifikatoriumi, po kurio pasirinktinai seka taškų atskirtų identifikatorių seka. Tipo pavadinimas arba žvaigždutė (*
) ir kabliataškis nutraukia šį teiginį.
Sintaksė atskleidžia dvi importo ataskaitos formas. Pirmiausia galite importuoti vieno tipo pavadinimą, kuris identifikuojamas per typeName
. Antra, galite importuoti visus tipus, kurie identifikuojami per žvaigždutę.
*
simbolis yra pakaitos simbolis, žymintis visus nekvalifikuotus tipų pavadinimus. Kompiliatorius liepia ieškoti tokių pavadinimų dešiniajame pakete importo sakinio paketų sekos, nebent tipo pavadinimas randamas anksčiau ieškotame pakete. Atkreipkite dėmesį, kad naudojant pakaitos simbolį nėra baudos už veikimą ar dėl to, kad kodas išsipučia. Tačiau tai gali sukelti vardų konfliktus, kuriuos pamatysite.
Pavyzdžiui, importuoti ca.javajeff.graphics.Triangle;
kompiliatoriui pasako, kad nekvalifikuotas Trikampis
klasė egzistuoja ca.javajeff.grafika
pakuotė. Panašiai kažkas panašaus
importuoti ca.javajeff.grafiką. *;
liepia kompiliatoriui pažvelgti į šį paketą, kai jis susiduria su Trikampis
vardas, a Apskritimas
vardas, ar net Sąskaita
vardas (jei Sąskaita
dar nebuvo rasta).
Venkite * daugelio kūrėjų projektuose
Dirbdami su kelių kūrėjų projektu, venkite naudoti *
pakaitos simbolis, kad kiti kūrėjai galėtų lengvai pamatyti, kurie tipai naudojami jūsų šaltinio kode.