Arv (Norsk)
I de foregående leksjonene har du sett arv nevnt flere ganger. På Java-språket kan klasser avledes fra andre klasser, og derved arve felt og metoder fra disse klassene.
Med unntak av
Object
, som ikke har noen superklasse, har hver klasse en og bare en direkte superklasse (enkelt arv). I fravær av noen annen eksplisitt superklasse, er hver klasse implisitt en underklasse av Object
. Klasser kan avledes fra klasser som er avledet fra klasser som er avledet fra klasser, og så videre, og til slutt avledet fra den øverste klassen,
Object
. En slik klasse sies å stamme fra alle klassene i arvekjeden som strekker seg tilbake til Object
. Ideen om arv er enkel, men kraftig: Når du vil opprette en ny klasse og det allerede er en klasse som inneholder noe av koden du vil ha, kan du utlede din nye klasse fra den eksisterende klassen . Ved å gjøre dette kan du bruke feltene og metodene til den eksisterende klassen uten å måtte skrive (og feilsøke!) Dem selv.
En underklasse arver alle medlemmene (felt, metoder og nestede klasser) fra sin superklasse. Konstruktører er ikke medlemmer, så de arves ikke av underklasser, men konstruktøren til superklassen kan påkalles fra underklassen.
Java Platform Class Hierarchy
Object
-klasse, definert i java.lang
-pakken, definerer og implementerer atferd som er felles for alle klasser – inkludert de du skriver. I Java-plattformen kommer mange klasser direkte fra Object
, andre klasser kommer fra noen av disse klassene, og så videre, og danner et hierarki av klasser.
Alle klasser i Java-plattformen er etterkommere av objekt
Øverst i hierarkiet er Object
den mest generelle av alle klasser. Klasser nær bunnen av hierarkiet gir mer spesialisert atferd.
Et eksempel på arv
Her er eksempelkoden for en mulig implementering av en Bicycle
klasse som ble presentert i klassen Classes and Objects:
En klassedeklarasjon for en MountainBike
klasse som er en underklasse av Bicycle
kan se slik ut:
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
arver alle feltene og metodene til Bicycle
og legger til feltet seatHeight
og en metode for å sette det. Med unntak av konstruktøren er det som om du hadde skrevet en ny MountainBike
klasse helt fra bunnen av, med fire felt og fem metoder. Du trengte imidlertid ikke alt arbeidet. Dette ville være spesielt verdifullt hvis metodene i Bicycle
-klassen var kompliserte og hadde tatt lang tid å feilsøke.
Hva du kan gjøre i en underklasse
En underklasse arver alle de offentlige og beskyttede medlemmene av foreldrene, uansett hvilken pakke underklassen er i. Hvis underklassen er i samme pakke som dens foreldre, arver det også pakkens private medlemmer av foreldrene. Du kan bruke de arvede medlemmene som de er, erstatte dem, skjule dem eller supplere dem med nye medlemmer:
- De arvede feltene kan brukes direkte, akkurat som alle andre felt.
- Du kan erklære et felt i underklassen med samme navn som det i superklassen, og dermed skjule det (anbefales ikke).
- Du kan erklære nye felt i underklassen som ikke er i superklassen.
- De arvede metodene kan brukes direkte som de er.
- Du kan skrive en ny forekomstmetode i underklasse det har samme signatur som den i superklassen, og overstyrer den.
- Du kan skrive en ny statisk metode i underklassen som har samme signatur som den i superklassen, og dermed skjule den.
- Du kan erklære nye metoder i underklassen som ikke er i superklassen.
- Du kan skrive en underklassekonstruktør som påkaller konstruktøren til superklassen, enten implisitt eller ved å bruke nøkkelordet
super
.
Følgende seksjoner i denne leksjonen utvides om disse emnene.
Private medlemmer i en superklasse
En underklasse arver ikke private
medlemmene av sin overordnede klasse. Imidlertid, hvis superklassen har offentlige eller beskyttede metoder for å få tilgang til sine private felt, kan disse også brukes av underklassen.
En nestet klasse har tilgang til alle de private medlemmene av den omsluttende klassen – både felt og metoder. Derfor har en offentlig eller beskyttet nestet klasse arvet av en underklasse indirekte tilgang til alle de private medlemmene av superklassen.
Casting Objects
Vi har sett at et objekt er av datatypen for klassen den ble instantiert fra. Hvis vi for eksempel skriver
public MountainBike myBike = new MountainBike();
så er myBike
av typen MountainBike
.
MountainBike
stammer fra Bicycle
og Object
. Derfor er en MountainBike
en Bicycle
og er også en Object
, og det kan være brukes uansett hvor Bicycle
eller Object
objekter blir etterlyst.
Det motsatte er ikke nødvendigvis sant: a Bicycle
kan være en MountainBike
, men det er ikke nødvendigvis. Tilsvarende kan en Object
være en Bicycle
eller en MountainBike
, men det er ikke nødvendigvis.
Casting viser bruken av et objekt av en skriv inn stedet for en annen type, blant gjenstandene som er tillatt av arv og implementeringer. Hvis vi for eksempel skriver
Object obj = new MountainBike();
så er obj
begge deler en Object
og en MountainBike
(inntil obj
tildeles et annet objekt som ikke er et MountainBike
). Dette kalles implisitt casting.
Hvis vi derimot skriver
MountainBike myBike = obj;
ville vi få en kompileringstidsfeil fordi obj
ikke er kjent for kompilatoren å være en MountainBike
. Vi kan imidlertid fortelle kompilatoren at vi lover å tildele en MountainBike
til obj
ved eksplisitt casting:
MountainBike myBike = (MountainBike)obj;
Denne rollebesetningen setter inn en kjøretidsjekk at obj
tildeles en MountainBike
slik at kompilatoren trygt kan anta at obj
er en MountainBike
. Hvis obj
ikke er MountainBike
under kjøretid, vil et unntak bli kastet.
instanceof
-operatøren. Dette kan redde deg fra en kjøretidsfeil på grunn av en feil rollebesetning. For eksempel:
if (obj instanceof MountainBike) { MountainBike myBike = (MountainBike)obj;}
Her verifiserer instanceof
-operatøren at obj
refererer til en MountainBike
slik at vi kan lage rollebesetningen med kunnskap om at det ikke blir noe unntak for kjøretid.