Java atbalsta klases atkārtotu izmantošanu, izmantojot mantojumu un sastāvu. Šī divu daļu apmācība māca, kā izmantot mantojumu Java programmās. 1. daļā jūs uzzināsiet, kā izmantot pagarina
atslēgvārdu, lai atvasinātu bērnu klasi no vecāku klases, izsauktu vecāku klases veidotājus un metodes un ignorētu metodes. 2. daļā jūs ceļosiet java.lang.Object
, kas ir Java superklase, no kuras manto katra cita klase.
Lai pabeigtu mācīšanos par mantošanu, noteikti pārbaudiet manu Java padomu, kurā paskaidrots, kad jāizmanto sastāvs pret mantojumu. Jūs uzzināsiet, kāpēc kompozīcija ir svarīgs mantojuma papildinājums, un kā to izmantot, lai pasargātu no problēmām ar iekapsulēšanu jūsu Java programmās.
lejupielādēt Iegūt kodu Lejupielādējiet šajā apmācībā avota kodu, piemēram, lietojumprogrammām. Izveidoja Jeff Friesen JavaWorld.Java mantošana: divi piemēri
Mantojums ir programmēšanas konstrukcija, kuras izveidošanai izmanto programmatūras izstrādātāji ir-attiecības starp kategorijām. Mantošana ļauj mums iegūt specifiskākas kategorijas no vispārīgākām. Konkrētāka kategorija ir veida vispārīgāka kategorija. Piemēram, norēķinu konts ir sava veida konts, kurā jūs varat veikt iemaksas un izmaksas. Līdzīgi kravas automašīna ir sava veida transportlīdzeklis, ko izmanto lielu priekšmetu vilkšanai.
Mantojums var samazināties vairākos līmeņos, izraisot arvien specifiskākas kategorijas. Piemēram, 1. attēlā parādīta automašīnu un kravas automašīnu mantošana no transportlīdzekļa; universāls, kas tiek mantots no automašīnas; un atkritumu vedējs, kas tiek mantots no kravas automašīnas. Bultas norāda no konkrētākām "bērnu" kategorijām (zemāk uz leju) uz mazāk specifiskām "vecāku" kategorijām (augstāk augšā).
Džefs FrīzensŠis piemērs ilustrē viens mantojums kurā bērnu kategorija manto stāvokli un uzvedību no vienas tiešās vecāku kategorijas. Turpretī vairākkārtēja mantošana ļauj bērnu kategorijai pārmantot stāvokli un uzvedību no divām vai vairākām vecāku kategorijām. 2. attēlā redzamā hierarhija ilustrē vairāku mantojumu.
Džefs FrīzensKategorijas ir aprakstītas pa klasēm. Java atbalsta vienotu mantošanu klases pagarinājums, kurā viena klase tieši pārmanto pieejamus laukus un metodes no citas klases, paplašinot šo klasi. Java tomēr neatbalsta vairāku mantošanu, izmantojot klases paplašināšanu.
Apskatot mantojuma hierarhiju, jūs varat viegli noteikt vairāku mantojumu, izmantojot dimanta modeli. 2. attēlā parādīts šis modelis saistībā ar transportlīdzekli, sauszemes transportlīdzekli, ūdens transportlīdzekli un gaisa spilvenu.
Paplašina atslēgvārdu
Java atbalsta klases paplašināšanu, izmantojot pagarina
atslēgvārds. Kad tas ir klāt, pagarina
norāda vecāku un bērnu attiecības starp divām klasēm. Zemāk es izmantoju pagarina
nodibināt attiecības starp klasēm Transportlīdzeklis
un Automašīna
un pēc tam starp Konts
un Krājkonts
:
Uzskaitīšana 1. The pagarina
atslēgvārds norāda vecāku un bērnu attiecības
klase Transportlīdzeklis {// dalībnieku deklarācijas} klase Automašīna paplašina transportlīdzekli {// mantot pieejamos dalībniekus no Transportlīdzekļa // sniedziet savu dalībnieku deklarācijas} sniedziet savu kontu {// dalībnieku deklarācijas} klase SavingsAccount paplašina kontu {// mantojiet pieejamos dalībniekus no konta // sniedziet pašu biedru deklarācijas}
The pagarina
atslēgvārds tiek norādīts aiz klases nosaukuma un pirms cita klases nosaukuma. Klases nosaukums iepriekš pagarina
identificē bērnu un klases vārdu pēc pagarina
identificē vecāku. Pēc tam nav iespējams norādīt vairākus klases nosaukumus pagarina
jo Java neatbalsta vairākkārtēju mantošanu pēc klases.
Šie piemēri kodē is-a attiecības: Automašīna
ir specializējies Transportlīdzeklis
un Krājkonts
ir specializējies Konts
. Transportlīdzeklis
un Konts
ir pazīstami kā bāzes klases, vecāku klasesvai superklases. Automašīna
un Krājkonts
ir pazīstami kā atvasinātas klases, bērnu klasesvai apakšklases.
Noslēguma klases
Jūs varētu pasludināt klasi, kuru nevajadzētu pagarināt; piemēram, drošības apsvērumu dēļ. Java valodā mēs izmantojam galīgais
atslēgvārds, lai novērstu dažu klašu pagarināšanu. Vienkārši pievienojiet klases galveni ar galīgais
, kā gala klases parole
. Ņemot vērā šo deklarāciju, kompilators ziņos par kļūdu, ja kāds mēģinās paplašināt Parole
.
Bērnu klases manto pieejamus laukus un metodes no vecāku klasēm un citiem priekštečiem. Viņi nekad nemanto konstruktorus. Tā vietā bērnu klases deklarē paši savus konstruktorus. Turklāt viņi var deklarēt savus laukus un metodes, lai tos atšķirtu no vecākiem. Apsveriet 2. sarakstu.
Saraksts 2. An Konts
vecāku klase
klases konts {private String name; privāta gara summa; Konts (virknes nosaukums, garā summa) {this.name = nosaukums; setAmount (summa); } anulētais depozīts (garā summa) {this.summa + = summa; } String getName () {atgriešanās nosaukums; } ilgi getAmount () {atgriešanas summa; } void setAmount (garā summa) {this.summa = summa; }}
2. saraksts apraksta vispārēju bankas kontu klasi, kurai ir nosaukums un sākotnējā summa, kuras abas ir iestatītas konstruktorā. Turklāt tas ļauj lietotājiem veikt iemaksas. (Jūs varat veikt izņemšanu, iemaksājot negatīvas naudas summas, taču mēs ignorēsim šo iespēju.) Ņemiet vērā, ka konta nosaukums ir jāiestata, izveidojot kontu.
Valūtas vērtību atspoguļošana
santīmu skaits. Jūs varētu vēlēties izmantot a dubultā
vai a peldēt
naudas vērtību glabāšanai, taču tas var izraisīt neprecizitātes. Lai iegūtu labāku risinājumu, apsveriet BigDecimal
, kas ir daļa no Java standarta klases bibliotēkas.
3. sarakstā ir a Krājkonts
bērnu klase, kas paplašina savu Konts
vecāku klase.
Saraksts 3. A Krājkonts
bērnu klase paplašina savu Konts
vecāku klase
klase SavingsAccount paplašina kontu {SavingsAccount (liela summa) {super ("uzkrājumi", summa); }}
The Krājkonts
klase ir niecīga, jo tai nav jādeklarē papildu lauki vai metodes. Tomēr tā paziņo par konstruktoru, kas inicializē laukus Konts
superklase. Inicializēšana notiek, kad Konts
konstruktoru izsauc caur Java super
atslēgvārds, kam seko iekavās iekļautais argumentu saraksts.
Kad un kur piezvanīt super ()
Gluži kā šis ()
jābūt pirmajam konstruktora elementam, kas izsauc citu konstruktoru tajā pašā klasē, super ()
jābūt pirmajam konstruktora elementam, kas izsauc konstruktoru tā augstākajā klasē. Ja jūs pārkāpjat šo kārtulu, kompilators ziņos par kļūdu. Sastādītājs arī ziņos par kļūdu, ja atklās super ()
izsaukt metodi; tikai kādreiz zvanīt super ()
konstruktorā.
4. saraksts vēl paplašinās Konts
ar Parbaudit kontu
klasē.
Saraksts 4. A Parbaudit kontu
bērnu klase paplašina savu Konts
vecāku klase
klase CheckingAccount paplašina kontu {CheckingAccount (garā summa) {super ("pārbaude", summa); } void izņemt (gara summa) {setAmount (getAmount () - summa); }}
Parbaudit kontu
ir nedaudz saturīgāks par Krājkonts
jo deklarē a atsaukt ()
metodi. Ievērojiet šīs metodes aicinājumus setAmount ()
un getAmount ()
, kas Parbaudit kontu
manto no Konts
. Jūs nevarat tieši piekļūt summa
lauks Konts
jo šis lauks ir deklarēts Privāts
(skat. 2. sarakstu).
super () un bez argumenta konstruktors
Ja super ()
nav norādīts apakšklases konstruktorā, un, ja augstākā klase nedeklarē a bez argumentiem
konstruktors, tad sastādītājs ziņos par kļūdu. Tas ir tāpēc, ka apakšklases konstruktoram jāzvana a bez argumentiem
superklases konstruktors kad super ()
nav klāt.
Klases hierarhijas piemērs
Esmu izveidojis AccountDemo
lietojumprogrammas klase, kas ļauj jums izmēģināt Konts
klases hierarhija. Vispirms ieskatieties AccountDemo
avota kods.
5. saraksts. AccountDemo
parāda kontu klases hierarhiju
klase AccountDemo {public static void main (String [] args) {SavingsAccount sa = jauns SavingsAccount (10000); System.out.println ("konta nosaukums:" + sa.getName ()); System.out.println ("sākotnējā summa:" + sa.getAmount ()); sa.deposit (5000); System.out.println ("jauna summa pēc depozīta:" + sa.getAmount ()); CheckingAccount ca = jauns CheckingAccount (20000); System.out.println ("konta nosaukums:" + ca.getName ()); System.out.println ("sākotnējā summa:" + ca.getAmount ()); apm. noguldījums (6000); System.out.println ("jauna summa pēc depozīta:" + ca.getAmount ()); apm. izņemt (3000); System.out.println ("jauna summa pēc izņemšanas:" + ca.getAmount ()); }}
The galvenais ()
Vispirms tiek parādīta 5. saraksta metode Krājkonts
, pēc tam Parbaudit kontu
. Pieņemot Konts.java
, SavingsAccount.java
, CheckingAccount.java
, un AccountDemo.java
avota faili atrodas tajā pašā direktorijā, lai apkopotu visus šos avota failus, izpildiet kādu no šīm komandām:
javac AccountDemo.java javac * .java
Lai palaistu lietojumprogrammu, izpildiet šādu komandu:
java AccountDemo
Jums jāievēro šāda izeja:
konta nosaukums: uzkrājuma sākotnējā summa: 10000 jauna summa pēc depozīta: 15000 konta nosaukums: sākotnējās summas pārbaude: 20000 jauna summa pēc depozīta: 26000 jauna summa pēc izņemšanas: 23000
Metodes ignorēšana (un metodes pārslodze)
Apakšklase var ignorēt (aizstāt) iedzimtu metodi, lai tā vietā tiktu izsaukta apakšklases versija. Galvenajai metodei jānorāda tāds pats nosaukums, parametru saraksts un atgriešanās veids kā metodei, kuru tiek ignorēta. Lai demonstrētu, esmu paziņojis izdrukāt ()
metodi Transportlīdzeklis
klase zemāk.
Saraksts 6. Deklarēšana a izdrukāt ()
metode tiek ignorēta
klases transportlīdzeklis {privāta virkne; privāts stīgu modelis; privāts int gads; Transportlīdzeklis (virknes marka, virknes modelis, gada gads) {this.make = marka; this.model = modelis; tas.gads = gads; } Virkne getMake () {return make; } String getModel () {atgriešanās modelis; } int getYear () {atgriešanās gads; } void print () {System.out.println ("Marka:" + izgatavot + ", Modelis:" + modelis + ", Gads:" + gads); }}
Tālāk es ignorēju izdrukāt ()
iekš Smagā mašīna
klasē.
Uzskaitīšana 7. Galvenais izdrukāt ()
iekšā Smagā mašīna
apakšklase
klases kravas automobilis pagarina transportlīdzekli {privātā dubultā tonnāža; Kravas automašīna (virknes marka, virknes modelis, vidējais gads, dubultā tonnāža) {super (marka, modelis, gads); this.tonnage = tonnāža; } double getTonnage () {atgriešanās tonnāža; } void print () {super.print (); System.out.println ("Tonnāža:" + tonnāža); }}
Smagā mašīna
's izdrukāt ()
metodei ir tāds pats nosaukums, atgriešanās tips un parametru saraksts kā Transportlīdzeklis
's izdrukāt ()
metodi. Ņemiet vērā arī to Smagā mašīna
's izdrukāt ()
metode vispirms izsauc Transportlīdzeklis
's izdrukāt ()
metodi, pievienojot prefiksu super.
uz metodes nosaukumu. Bieži vien ir ieteicams vispirms izpildīt superklases loģiku un pēc tam izpildīt apakšklases loģiku.
Virsklases metožu izsaukšana no apakšklases metodēm
Lai izsauktu virsklases metodi no galvenā apakšklases metodes, metodes nosaukumam pievienojiet rezervēto vārdu super
un dalībnieku piekļuves operators. Pretējā gadījumā jūs rekursīvi izsauksit apakšklases svarīgāko metodi. Dažos gadījumos apakšklase maskēsPrivāts
superklases lauki, deklarējot tā paša nosaukuma laukus. Tu vari izmantot super
un dalībnieka piekļuves operatoram piekļūtPrivāts
superklases lauki.
Lai pabeigtu šo piemēru, esmu izvilkis a VehicleDemo
klases galvenais ()
metode:
Kravas automašīna = jauna kravas automašīna ("Ford", "F150", 2008, 0,5); System.out.println ("Make =" + truck.getMake ()); System.out.println ("Model =" + truck.getModel ()); System.out.println ("Year =" + truck.getYear ()); System.out.println ("Tonnage =" + truck.getTonnage ()); truck.print ();
Pēdējā līnija truck.print ();
, zvani smagā mašīna
's izdrukāt ()
metodi. Šī metode vispirms izsauc Transportlīdzeklis
's izdrukāt ()
izlaist kravas automašīnas marku, modeli un gadu; tad tas izsniedz kravas automašīnas tonnāžu. Šī izejas daļa ir parādīta zemāk:
Marka: Ford, Modelis: F150, Gads: 2008 Tonnāža: 0.5
Izmantojiet finālu, lai bloķētu metodes ignorēšanu
Dažreiz drošības vai cita iemesla dēļ jums, iespējams, būs jāpaziņo par metodi, kuru nevajadzētu ignorēt. Jūs varat izmantot galīgais
šim nolūkam. Lai novērstu ignorēšanu, vienkārši pievienojiet metodes galveni ar galīgais
, kā galīgā virkne getMake ()
. Pēc tam kompilators ziņos par kļūdu, ja kāds mēģinās ignorēt šo metodi apakšklasē.
Metodes pārslodze salīdzinājumā ar primāro
Pieņemsim, ka jūs nomainījāt izdrukāt ()
metodi 7. sarakstā ar zemāk norādīto:
void print (virknes īpašnieks) {System.out.print ("Īpašnieks:" + īpašnieks); super.druka (); }
Modificētais Smagā mašīna
klasē tagad ir divi izdrukāt ()
metodes: iepriekšējā skaidri deklarētā metode un no tās mantotā metode Transportlīdzeklis
. The void print (virknes īpašnieks)
metode netiek ignorēta Transportlīdzeklis
's izdrukāt ()
metodi. Tā vietā tā pārslodzes to.
Jūs varat noteikt mēģinājumu pārslogot, nevis aizstāt metodi sastādīšanas laikā, pirms apakšklases metodes galvenes pievienojot @ Pārvarēt
anotācija:
@Override void print (virknes īpašnieks) {System.out.print ("Īpašnieks:" + īpašnieks); super.druka (); }
Norādot @ Pārvarēt
sastādītājam stāsta, ka dotā metode ignorē citu metodi. Ja kāds mēģinātu pārslogot metodi, kompilators ziņotu par kļūdu. Bez šīs anotācijas kompilators neziņotu par kļūdu, jo metodes pārslodze ir likumīga.
Kad lietot @Override
Izveidojiet paradumu prefiksēt primāras metodes ar @ Pārvarēt
. Šis ieradums palīdzēs daudz ātrāk atklāt pārslodzes kļūdas.