class Book { String title; } class Dictionary extends Book { int wordcount; } class CartoonAlbum extends Book { int stripcount; }

Like dokumenter
Arv. Book book1 = new Book(); book1. title = "Sofies verden" class Book { String title; } class Dictiona ry extends Book {

Læringsmål for forelesningen

Repitisjonskurs. Arv, Subklasser og Grensesnitt

Forklaring til programmet AbstraktKontoTest.java med tilhørende filer Konto.java, KredittKonto.java, SpareKonto.java

INF1010 våren 2008 Uke 4, 22. januar Arv og subklasser

Eksekveringsrekkefølgen (del 1) Oppgave 1. Eksekveringsrekkefølgen (del 2) Kommentar til oppgave 1. } // class Bolighus

TDT4100 Objektorientert programmering

Konstruktører. Bruk av konstruktører når vi opererer med "enkle" klasser er ganske ukomplisert. Når vi skriver. skjer følgende:

Læringsmål for forelesningen

Post-it spørsmål fra timen (Arv og subklasser)

Læringsmål for forelesningen

TDT4100 Objektorientert programmering

EKSAMEN I FAG TDT4100 Objekt-orientert programmering. Fredag 3. juni 2005 KL

TDT4100 Objektorientert programmering

Kapittel 7: Mer om arv

Introduksjon til objektorientert programmering

INF1010 våren Arv og subklasser del 1

INF1010 våren Arv og subklasser del 1

INF1010 Arv. Marit Nybakken 2. februar 2004

2 Om statiske variable/konstanter og statiske metoder.

Eksamen Oppgave a) public class DayTime { public final int hours, minutes;

Kapittel 6: Arv. Redigert av: Khalid Azim Mughal

Eksamensoppgave i TDT4100 Objektorientert programmering med Java

Eksamensoppgave i TDT4100 Objektorientert programmering med Java

Gjennomgang av eksamen H99

Hva er verdien til variabelen j etter at følgende kode er utført? int i, j; i = 5; j = 10; while ( i < j ) { i = i + 2; j = j - 1; }

TDT4100 Objektorientert programmering

Beskrivelse av programmeringsspråket Compila15 INF Kompilatorteknikk Våren 2015

UNIVERSITETET I OSLO

INF1010 våren Arv og subklasser - del 2

Introduksjon til objektorientert. programmering. Hva skjedde ~1967? Lokale (og globale) helter. Grunnkurs i objektorientert.

En klasse som arver, eller selv deklarerer en abstrakt metode, må deklareres som abstrakt.

Oppsummering. Kort gjennomgang av klasser etc ved å løse halvparten av eksamen Klasser. Datastrukturer. Interface Subklasser Klasseparametre

Delegeringsteknikken. public class CD { private List<Tra ck> tracks = new ArrayLis t<track> (); public int gettrack Count() { return tracks.

INF1000 EKSTRATILBUD. Stoff fra uke 1-5 (6) 3. oktober 2012 Siri Moe Jensen

EKSAMEN 6108/6108N PROGRAMMERING I JAVA Alt trykt og skriftlig materiale.

2 Om statiske variable/konstanter og statiske metoder.

UNIVERSITETET I OSLO

Object interaction. Innhold. Abstraksjon Grunnleggende programmering i Java Monica Strand 3. september 2007.

Del 3: Evaluere uttrykk

IN1010 våren 2018 Tirsdag 15. mai. Repetisjon av subklasser og tråder. Stein Gjessing Institutt for informatikk Universitetet i Oslo

IN1010 V19, Obligatorisk oppgave 2

klassen Vin må få en ny variabel Vin neste alle personvariable (personpekere) i listeklassen må byttes til Vin

Innhold uke 4. INF 1000 høsten 2011 Uke 4: 13. september. Deklarasjon av peker og opprettelse av arrayobjektet. Representasjon av array i Java

Argumenter fra kommandolinjen

Generiske mekanismer i statisk typede programmeringsspråk

Av Stein Gjessing, Institutt for informatikk, Universitetet i Oslo

INF1010 våren Arv og subklasser - del 2

TDT4100 Objektorientert programmering

OO-eksempel. Modellen ser slik ut: Studenter + antstudenter : int = 0

EKSAMENSFORSIDE Skriftlig eksamen med tilsyn

INF våren 2017

IN1010 våren 2018 Tirsdag 6. februar. Arv og subklasser - del 2

Løsningsforslag til Eksamen i fag SIF8005 Programmering. Torsdag 10. mai 2001 kl

Innhold uke 9. Objektorientert programmering i Python. Om ukens pensum. Referanser og objekter Tema: Mer komplekse strukturer

Tillatte hjelpemidler: alle skrevne og trykte. Antall sider: 2 (+ 1 side vedlegg, bakerst). Oppgave 1 [25%]

EKSAMEN I FAG TDT4100 Objektorientert programmering. Fredag 6. juni 2008 Kl

løsningsforslag-uke5.txt

JAVA Oppsummering for IS-102. Even Åby Larsen

TDT Prosedyre- og objektorientert programmering

LC191D Videregående programmering Høgskolen i Sør-Trøndelag, Avdeling for informatikk og e-læring. Else Lervik, januar 2012.

BOKMÅL Side 1 av 7. KONTINUASJONSEKSAMEN I FAG TDT4100 Objektorientert programmering / IT1104 Programmering, videregående kurs

public class NaivRiking { private HeldigSnylter minsnylter; public NaivRiking(HeldigSnylter h) { minsnylter = h;

Obligatorisk oppgave 4: Lege/Resept

LO191D/LC191D Videregående programmering

Algoritmer og datastrukturer Kapittel 3 - Delkapittel 3.1

Tittel Objektorientert systemutvikling 3

EKSAMEN. Objektorientert programmering

UNIVERSITETET I OSLO

Sortering med Comparable og Comparator

Informasjon Prøveeksamen i IN1000 høsten 2018

Eksamen. Objektorientert Programmering IGR 1372

Dagens tema: 12 gode råd for en kompilatorskriver

Account. valideringslogikken. Det er vanligst å bruke en såkalt unchecked exception (usjekket unntak), som IllegalArgumentException.

LITT OM OPPLEGGET. INF1000 EKSTRATILBUD Stoff fra uke September 2012 Siri Moe Jensen EKSEMPLER

IN våren 2018 Tirsdag 16. januar

Dagens tema: 12 gode råd for en kompilatorskriver. Sjekking av navn. Lagring av navn. Hvordan finne et navn?

1- og 2-veis Innkapsling Java Stabel Kø Prio-kø Iterator. Enveis- og toveislister Innkapsling («boxing») (Big Java 6.8.5)

INF1010 våren Arv og subklasser - del 2

INF1010 våren 2017 Torsdag 2. februar. Arv og subklasser - del 2

i=0 Repetisjon: arrayer Forelesning inf Java 4 Repetisjon: nesting av løkker Repetisjon: nesting av løkker 0*0 0*2 0*3 0*1 0*4

Forelesning inf Java 4

INF1010 våren februar. Arv og subklasser, del 2. Repetisjon. Repetisjon - Biler. Repetisjon: Klasser - Subklasser

Hva er en metode. Hva skjer når vi kaller en metode

INF1010 våren februar. Arv og subklasser, del 2

EKSAMENSFORSIDE SKRIFTLIG EKSAMEN

Objektorientert programmering i Python. Resten av semesteret. Innhold uke 9 Mer komplekse strukturer. Referanser og objekter, inkl Mentimeter spørsmål

ANTDAGER = 358; I Ifra nyttår 08 til 08 1ed julaften

INF1000: Forelesning 7

1- og 2-veis Innkapsling Java Stabel Kø Prio-kø Iterator. Enveis- og toveislister Innkapsling («boxing») (Big Java 6.8.5)

Tråder Repetisjon. 9. og 13. mai Tråder

UNIVERSITETET I OSLO

INF1000 (Uke 15) Eksamen V 04

INF1000 (Uke 15) Eksamen V 04

2012 2a. C rc; void main() { rc = new C (); rc.m2(); } } INF 3110/ INF /28/13 1

Kapittel 8: Programutvikling

UNIVERSITETET I OSLO

Dagens tema: Mer av det dere trenger til del 1

Kontinuasjonseksamensoppgave i TDT4100 Objektorientert programmering

Transkript:

Arv 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. class Book { String title; class Dictionary extends Book { int wordcount; Notasjon for arv: Dictionary og CartoonAlbum arver fra Book class CartoonAlbum extends Book { int stripcount; En instans av hver klasse, hvor Dictiona e har tilstand som delvis er arvet fra Boo Java-kode med bruk av nøkkelordet extends I eksemplet over vil Dictionary og CartoonAlbum begge være subklasser av Book, og omvendt så vil Book være superklassen til både Dic tionary 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 og typer og (deklarasjonen av) typen til variabler og tilordninger 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 CartoonAlb um. 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 Class Book Dictionary CartoonAlbum book1 true false false nynorsk true true false flatfirer true false true Vi ser altså at alle objektene er instanceof Book og at book1 ikke er instanceof de to subklassene. 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 som T. Situasjonen 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 book1 = book2; // OK siden book2 er deklarert som Book og dette er samme type som book1-variablen book1 = dict1; // OK siden dict1 er deklarert som Dictionary og dette er en subklasse av typen til book1-variablen book1 = cartoon1; // OK siden cartoon1 er deklarert som CartoonAlbum og dette er en subklasse av typen som book1-variablen er deklarert som dict1 = book2; // ikke OK siden book2 er deklarert som Book og dette ikke er samme eller en subtype av Dictionary dict1 = dict2; // OK siden dict2 er deklarert som Dictionary og dette er samme type som dict1-variablen dict1 = cartoon1; // ikke OK siden cartoon1 er deklarert som CartoonAlbum og dette ikke er samme eller en subtype av Dictionary Regelen er altså at en variable (eller felt eller parameter) av type T bare kan tilordnes verdien av et uttrykk, når uttrykket har type T eller en subklasse av type T. Et vesentlig poeng er skillet mellom typen til uttrykket og typen til verdien av uttrykket, som er illustrert av følgende setninger: Book book = new Dictionary(); // OK, se over Dictionary dict = book; // ikke OK, selv om book faktisk refererer til en instans av Dictionary, så er det typen til book-variablen som sjekkes og som må være Dictionary eller en Dictionary-subklasse Typen til et uttrykk kan lese direkte av (typen til delene av) uttrykket, mens det andre krever at en kjører koden og ser hva slags verdi en faktisk får. Dersom en skal ha garantier om at noe alltid er lov, må en altså se på typen til uttrykket og ikke vente til kjøretid og sjekke typen til verdien av uttrykket. Dette ser en enklest med følgende setning: Dictionary dict = (Math.random() < 0.5? new Book() : new Dictionary()); // ikke OK, fordi typen til if-uttrykket er Book Selv om en i (omtrent) annenhvert tilfelle får en (referanse til en) Dictionary som verdi av uttrykket, så kan en bare garantere at resultatet blir en Book og da kan en ikke tillate tilordningen. Innkapsling Ved innkapsling så prøver en å sikre korrekt bruk av metoder og konsistent tilstand, bla. ved å sikre at tilstanden initialiseres og at argumenter valideres. Anta at Book er skrevet som vist under, for å kapsle inn tilstanden ordentlig:

public class Book { private String title; public Book(String settitle(title); public String gettitle() { return title; if (! <sjekk at title bare inneholder bokstaver og tall>) { IllegalArgumentException("Book titles can only contain letters and digits"); // Feil!!! private int wordcount; // ingen initialisering av titl public Dictionary(int wordcount this.wordcount = wordcount; // egen validering av title if (! <sjekk at title slutte på 'ordbok'>) { IllegalArgumentException("Dictiona titles must end with 'ordbok'"); Denne koden sikrer to ting: 1) at title-attributtet får en initiell verdi og 2) at title-verdien alltid er en String med kun bokstaver og tall. Dette påvirker ikke bare hva andre klasser kan gjøre med Book-instanser, men også hva Dictionary og CartoonBook kan gjøre med sine instanser, siden de jo også er Book-instanser og derfor må følge reglene for slike. F.eks. kan ikke subklassene utelate initialisering og heller ikke slakke på kravene som stilles til tegnene i en title. Koden i midten høyre prøver begge deler og må derfor avvises. Mer spesifikt vil en få feilmelding om at 1) konstruktøren ikke kaller en konstruktør i superklassen og 2) at title-attributtet ikke er synlig og derfor ikke kan settes i s ettitle-metoden. Alternativet er koden til høyre, hvor super-nøkkelordet brukes på to måter: 1) til å kalle superklassens konstruktør (kan bare gjøres i konstruktøren) og 2) til å kalle superklassens settitle-metode (kan gjøres i alle metoder). Innkapslingen i Book-klassen er imidlertid fortsatt vanntett, så Dictionary-klassen kan fortsatt ikke omgå valideringen i superklassens settitl e-metode og dermed slakke på kravene. Dette kan løses på to måter, enten ved å åpne opp for direkte tilgang til title-attributtet, men kun for subklasser eller ved å la subklassen redefinere valideringslogikken. Subklasse-synlighet med protected-modifikatoren Det finnes en egen synlighetsmodifikator som gir subklasser tilgang til attributter og metoder definert i en superklasse, nemlig protected. Dette kan brukes for å gi Dictionary-subklassen direkte tilgang til title-attributtet og dermed muligheten til å omgå valideringen:

public class Book { protected String title; if (! ) { IllegalArgumentException(); if (! ) { IllegalArgumentException(); // fordi title-attributtet er deklarert med protected, // så har vi nå lov til å endre det direkte Bruk og redefinering av metoder En annen teknikk for å la en subklasse definere alternative regler for oppførsel, er å skille ut logikk i egne metoder som kan redefineres. Anta f.eks. at en forutser behovet for å definere subklasse-spesifikke regler for gyldige title-verdier. Dette kan håndteres som vist under: public class Book { private String title; protected boolean isvalidtitle(string return <true hvis title bare inneholder bokstaver og tall, og false ellers> if (! isvalidtitle(title)) { IllegalArgumentException(); @Override protected boolean isvalidtitle(string return <true hvis title slutter på 'ordbok', og false ellers> I Book-koden over har en lagt valideringslogikken i en egen isvalidtitle-metode, som er gjort synlig for subklassene med protected-modifik atoren. Dictionary-klassen redefinerer denne metoden med sin egen logikk. Hvis en kaller settitle på et objekt instansiert som Book, så vil

Book-klassen sin isvalidtitle-metode bli kalt. Men dersom objektet er en Dictionary-instans, så vil (den redefinerte) metoden i Dictionary-k lassen bli brukt i stedet. Dermed kan Dictionary-spesifikke valideringsregler overstyre valideringsreglene i Book, som jo var intensjonen. Dic tionary-klassen får altså fortsatt ikke direkte tilgang til title-attributtet, men får lov til å endre/overstyre valideringslogikken. Ved hjelp av protected-modifikatoren og redefinering av metoder kan altså en superklasse tillate at visse regler endre/overstyres av en subklasse. Dersom subklassen ønsker å bruke reglene til superklassen, så kan en (selektivt) bruke metodekall med super-nøkkelordet. Dictionary-klassen kan f.eks. kalle super.isvalidtitle(title) hvis den ønsker å (gjen)bruke superklassens logikk. Sidetype Ferdig Dekningsgrad Omfang teori 95 50 50