Perintö
Edellisissä oppitunneissa olet nähnyt perimisen mainittavan useita kertoja. Java-kielellä luokat voidaan johtaa muista luokista, jolloin peritään kentät ja menetelmät näistä luokista.
Lukuun ottamatta
Object
, jolla ei ole yliluokkaa, jokaisella luokassa on yksi ja vain yksi suora superluokka (yksi perintö). Jos muuta nimenomaista yliluokkaa ei ole, jokainen luokka on implisiittisesti Object
-alaluokka. Luokat voidaan johtaa luokista, jotka on johdettu luokista johdetuista luokista, ja niin edelleen ja johtuu lopulta ylimmästä luokasta,
Object
. Tällaisen luokan sanotaan polveutuvan kaikista perintöketjun luokista, jotka ulottuvat takaisin Object
. Perintöidea on yksinkertainen, mutta tehokas: Kun haluat luoda uuden luokan ja jo on olemassa luokka, joka sisältää osan haluamastasi koodista, voit johtaa uuden luokan olemassa olevasta luokasta. . Tällöin voit käyttää uudelleen olemassa olevan luokan kenttiä ja menetelmiä tarvitsematta kirjoittaa niitä itse (ja virheenkorjausta!).
Alaluokka perii kaikki jäsenet (kentät, menetelmät ja sisäkkäiset luokat) sen superluokka. Rakentajat eivät ole jäseniä, joten alaluokat eivät peri niitä, mutta yliluokan rakentaja voidaan kutsua alaluokasta.
Java-alustaluokan hierarkia
Object
-luokka, joka on määritelty paketissa java.lang
, määrittelee ja toteuttaa kaikille luokille yhteisen käyttäytymisen – myös kirjoittamillesi luokille. Java-alustalla monet luokat ovat peräisin suoraan divista Object
, muut luokat ovat peräisin joistakin näistä luokista ja niin edelleen ja muodostavat luokkien hierarkian.
Kaikki Java-alustan luokat ovat objektin jälkeläisiä
Hierarkian yläosassa Object
on yleisin kaikista luokista. Hierarkian alaosassa olevat luokat tarjoavat erikoistuneempaa käyttäytymistä.
Esimerkki perinnöstä
Tässä on esimerkkikoodi Bicycle
luokka, joka esitettiin Luokat ja objektit -oppitunnilla:
Luokan ilmoitus MountainBike
-luokalle, joka on saattaa näyttää tältä:
public class MountainBike extends Bicycle { // the MountainBike subclass adds one field public int seatHeight; // the MountainBike subclass has one constructor public MountainBike(int startHeight, int startCadence, int startSpeed, int startGear) { super(startCadence, startSpeed, startGear); seatHeight = startHeight; } // the MountainBike subclass adds one method public void setHeight(int newValue) { seatHeight = newValue; } }
MountainBike
perii kaikki Bicycle
-kentät ja -menetelmät ja lisää kentän seatHeight
ja menetelmän sen asettamiseksi. Rakentajaa lukuun ottamatta on kuin olisit kirjoittanut uuden luokan MountainBike
kokonaan tyhjästä, neljällä kentällä ja viidellä menetelmällä. Sinun ei kuitenkaan tarvinnut tehdä kaikkea työtä. Tämä olisi erityisen arvokasta, jos Bicycle
-luokan menetelmät olisivat monimutkaisia ja niiden virheenkorjaukseen olisi kulunut paljon aikaa.
Mitä voit tehdä alaluokassa
Aliluokka perii kaikki vanhemmansa kaikki julkiset ja suojatut jäsenet riippumatta siitä, mihin pakettiin alaluokka kuuluu. Jos aliluokka on samassa paketissa kuin alaluokka vanhempi, se myös perii vanhemman paketin yksityiset jäsenet. Voit käyttää perittyjä jäseniä sellaisenaan, korvata ne, piilottaa ne tai täydentää niitä uusilla jäsenillä:
- Peritetyt kentät voivat käyttää suoraan, kuten kaikkia muita kenttiä.
- Voit ilmoittaa alaluokan kentän samalla nimellä kuin yliluokan kenttä, piilottaen sen siten (ei suositella).
- Voit ilmoittaa alaluokan uudet kentät, jotka eivät ole yliluokassa.
- Perittyjä menetelmiä voidaan käyttää suoraan sellaisina kuin ne ovat.
- Voit kirjoittaa uuden ilmentymämenetelmän alaluokka on sama allekirjoitus kuin yliluokan, mikä ohittaa sen.
- Voit kirjoittaa alaluokkaan uuden staattisen menetelmän, jolla on sama allekirjoitus kuin yliluokassa, piilottaen sen siten.
- Voit ilmoittaa alaluokassa uudet menetelmät, jotka eivät ole yläluokkaa.
- Voit kirjoittaa aliluokan konstruktorin, joka kutsuu yliluokan rakentajan joko implisiittisesti tai käyttämällä avainsanaa
super
.
Seuraavat tämän oppitunnin kohdat laajentavat näitä aiheita.
Yksityiset jäsenet yliluokassa
Alaluokka ei peri vanhempiensa luokan private
jäseniä. Jos kuitenkin yliluokalla on julkisia tai suojattuja menetelmiä pääsyyn yksityisiin kenttiin, niitä voi käyttää myös alaluokka.
Sisäkkäisellä luokalla on pääsy kaikkiin sen sulkevan luokan yksityisiin jäseniin – sekä kenttiin että menetelmiin. Siksi alaluokan perimällä julkisella tai suojatulla sisäkkäisellä luokalla on epäsuora pääsy kaikkiin yläluokan yksityisiin jäseniin.
Objektien lähettäminen
Olemme havainneet, että objekti kuuluu sen luokan tietotyyppi, josta se on tehty. Jos esimerkiksi kirjoitamme
public MountainBike myBike = new MountainBike();
, niin myBike
on tyyppiä MountainBike
.
MountainBike
on polku Bicycle
ja Object
. Siksi MountainBike
on Bicycle
ja on myös Object
, ja se voidaan käytetään missä tahansa Bicycle
– tai Object
-objekteja tarvitaan.
Käänteinen ei välttämättä ole totta: = ”5010a393ca”> voi olla MountainBike
, mutta se ei välttämättä ole. Vastaavasti Object
voi olla Bicycle
tai MountainBike
, mutta se ei välttämättä ole.
Suoratoisto osoittaa yhden objektin käytön kirjoita toisen tyypin sijaan perimisen ja toteutusten sallimien kohteiden joukossa. Jos esimerkiksi kirjoitamme
Object obj = new MountainBike();
, niin obj
on sekä Object
ja MountainBike
(kunnes obj
on määritetty toinen objekti, joka ei ole MountainBike
). Tätä kutsutaan implisiittiseksi suoratoistoksi.
Jos taas kirjoitamme
MountainBike myBike = obj;
haluaisimme hanki käännösaika-virhe, koska obj
ei ole kääntäjän tiedossa olevan MountainBike
. Voimme kuitenkin kertoa kääntäjälle, että lupaamme antaa MountainBike
-kohdan obj
nimenomaisella suoratoistolla:
MountainBike myBike = (MountainBike)obj;
Tämä suoratoisto lisää ajonaikaisen tarkistuksen, että obj
on määritetty MountainBike
jotta kääntäjä voi olettaa turvallisesti, että obj
on MountainBike
. Jos obj
ei ole MountainBike
ajon aikana, heitetään poikkeus.
instanceof
-operaattorin avulla. Tämä voi säästää sinut virheellisestä suoratoistosta johtuvasta ajonaikaisesta virheestä. Esimerkiksi:
if (obj instanceof MountainBike) { MountainBike myBike = (MountainBike)obj;}
Tässä instanceof
-operaattori tarkistaa, että obj
viittaa MountainBike
-sivuun, jotta voimme tehdä näyttelijät tietäen, ettei ajonaikaista poikkeusta tule heittää.