You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 11 Next »

Arv (eng: inheritance) er en mekanisme for å bygge videre på eksisterende klasser og regnes ofte som varemerket til objektorientert programmering. Når arv brukes riktig, kan den gjøre koden ryddigere og enklere å gjenbruke.

En klasse definerer hvilken tilstand og oppførsel instanser av klassen vil ha, hvor tilstanden er alle attributtene (i Java kalles det felt) og oppførselen er metodene (og reglene for hva de gjør). Med arv(ingsmekanismen) kan en si at en ny klasse utvider en eksisterende klasse, slik at instansene av den nye klassene får en tilstanden og oppførsel som er kombinasjonen av det som er definert i den eksisterende og den nye klassen. Et eksempel er vist i tabellen under, hvor en Book-klasse definerer attributtet title og Dictionary og CartoonAlbum utvider denne med henholdsvis attributtene wordCount og stripCount.

BookString titleDictionaryint wordCountCartoonAlbumint stripCount

Notasjon for arv: Dictionary og CartoonAlbum arver fra Book

class Book {
	String title;
}

class Dictionary extends Book {
	int wordCount;
}

class CartoonAlbum extends Book {
	int stripCount;
} 

Java-kode med bruk av nøkkelordet extends

1.book1: Booktitle = "Sofies verden"1.nynorsk: Dictionarytitle = "Nynorskordboken"wordCount = 327681.flatFirer: CartoonAlbumtitle = "Flat firer"stripCount = 128

En instans av hver klasse, hvor Dictionary og CartoonAlbum-instansene har tilstand som delvis er arvet fra Book.

Book book1 = new Book();
book1.title = "Sofies verden"

Dictionary nynorsk = new Dictionary();
nynorsk.title = "Nynorskordboken"
nynorsk.wordCount = 32768

CartoonAlbum flatFirer = new CartoonAlbum();
flatFirer.title = "Flat firer"
flatFirer.stripCount = 128

Java-kode for å opprette og initialisere instanser.

I eksemplet over vil Dictionary og CartoonAlbum begge være subklasser av Book, og omvendt så vil Book være superklassen til både Dictionary og CartoonAlbum. Sammen danner de et klassehierarki, som i dette tilfellet er på to nivåer, men som generelt ikke har noe begrensninger på størrelsen.

Arvingsmekanismen er i bunn og grunn enkel, men det kompliseres litt av to faktorer:

  • sammenhengen mellom instansiering, typen til objekter og (deklarasjonen av) typen til variabler
  • regler for oppførsel og innkapsling

Instanser og typer, deklarasjoner og tilordninger

De tre objektene identifisert som book1, nynorsk og flatFirer er instanser av hver sin klasse, henholdsvis Book, Dictionary og CartoonAlbum. Samtidig, og her starter gjerne forvirringen, så sier vi at #nynorsk og #flatFirer også er instanser av eller er av typen Book, fordi de har alle egenskapene til Book-instanser og derfor kan betraktes som slike. Hvis en f.eks. bruker instanceof-operatoren i Java så vil den virke som vist i tabellen under:

object instanceof ClassBookDictionaryCartoonAlbum
book1truefalsefalse

nynorsk

truetruefalse
flatFirertruefalsetrue

Vi ser altså at alle objektene er instanceof Book og at book1 ikke er instanceof de to subklassene. Så hvis en altså sier at et objekt er en instans av en bestemt type T, så betyr det ikke nødvendigvis at en brukte new T(...) for å lage den, men new <T eller en subklasse av T>(...). Dette er analogt med at en kan si at et objekt er en instans av (grensesnittet) Iterator, selv om en en nødvendigvis ikke har brukt new Iterator for å opprette objektet. Hvis en ønsker å si nettopp det at en brukte new T(...) så kan en kanskje si at objektet ble instansiert med T.

Sitiuasjonen er nokså tilsvarende med deklarasjoner og tilordninger. Når en deklarerer en variabel (eller felt eller parameter) til å være av en type T, så sier en at denne variablen bare kan tilordnes instanser av T, eller mer presist, at den bare kan tilordnes verdien av uttrykk som har typen T. I koden under vises ulike tilfeller og kommentaren angir om det er lov eller ikke og hvorfor.

Book book1 = new Book(); // OK siden new Book() gir et object av typen Book
Book book2 = new Dictionary(); // OK siden new Dictionary() gir et objekt av typen Book
Book book3 = new CartoonAlbum(); // OK siden new CartoonAlbum() gir et objekt av typen Book

Dictionary dict1 = new Book(); // ikke OK siden new Book() ikke gir et object av typen Dictionary
Dictionary dict2 = new Dictionary(); // OK siden new Dictionary() gir et objekt av typen Dictionary
Dictionary dict3 = new CartoonAlbum(); // ikke OK siden new CartoonAlbum() ikke gir et objekt av typen Dictionary

CartoonAlbum cartoon1 = new Book(); // ikke OK siden new Book() ikke gir et object av typen CartoonAlbum
CartoonAlbum cartoon2 = new Dictionary(); // ikke OK siden new Dictionary() gir et objekt av typen CartoonAlbum
CartoonAlbum cartoon3 = new CartoonAlbum(); // OK siden new CartoonAlbum() gir et objekt av typen CartoonAlbum

book1 = book2; // OK siden book2 er deklarert som Book og dette er samme type som book1-variablen er deklarert som 
book1 = dict1; // OK siden dict1 er deklarert som Dictionary og dette er en subklasse av typen som book1-variablen er deklarert som
book1 = cartoon1; // OK siden cartoon1 er deklarert som CartoonAlbum og dette er en subklasse av typen som book1-variablen er deklarert som

 

 

 

  • No labels