Programmēšana

Mantošana Java, 1. daļa: paplašinātais atslēgvārds

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īzens

Kategorijas 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šīnaun 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šīnair specializējies Transportlīdzeklis un Krājkontsir 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 Kontskonstruktoru 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 AccountDemoavota 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.

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