Title: Kun til bruk i tilknytning til l
1Arv og polymorfi
Repetisjon fra kap. 4 side 2-3 Generalisering
og spesialisering side 4-5 Arv side
6-8 Polymorfi side 9Gyldige tilordninger,
referanser til objekter side 10 Abstrakte
klasser side 11 Hva hvis polymorfi ikke hadde
eksistert? side 12 Når har vi behov for å bruke
instanceof? side 13 Tilgangsmodifikatorer side
14-16Oppussingseksemplet, del 3 side 17-18 Arv
i to nivåer side 19 Definisjoner og
regler side 20-25 Interface side 26-29
2superklassen til alle andre klasser
Object
Repetisjon fra kapittel 4
Et utsnitt avklassetreet i Java
setSize(), setVisible(),setBackground() og
getBackground() arves herfra
Component
subklasse til Object og Component
Container
add() arves herfra
superklasse til JPanel og Tegning
Window
JComponent
setTitle() arves herfra
Frame
JPanel
JFrame
Tegning
setDefaultCloseOperation() og getContentPane(), s
amt revidert utgave av add() arves herfra
Vindu
3Objektene som de ulike klassenebeskriver utgjør
mengder
Repetisjon fra kapittel 4
Container
Window
JComponent
JPanel
Frame
JFrame
Tegning
Vindu
4Generalisering og spesialisering
Object
Ansatt
Student
. . .
Person
fnr navn adr studnr
fnr navn adr lønnstrinn
resten av klassetreet
-fnr -navn -adr
finnFnr finnNavn finnAdresse finnStudnr
finnFnr finnNavn finnAdresse finnLønnstrinn
finnFnr finnNavn finnAdresse
generalisering, superklasse
Ansatt
Student
spesialiseringer, subklasser
-studnr
-lønnstrinn
finnStudnr
finnLønnstrinn
5Hva forteller klassetreet?
Person
Alle ansatte er en delmengde av alle
personer. Alle studenter er en delmengde av alle
personer.
En student er en person. En ansatt er en person.
Ansatt
Student
Et klassetre viser et forhold som eksistererer
mellom klasser. En klasse er en
generalisering/spesialisering av en annen
klasse. Pilen går fra den spesialiserte klassen
til den generaliserte klassen. Må ikke
forveksles med assosiasjon. En assosiasjon mellom
to klasser uttrykker at det eksisterer et
forhold mellom objektene av de involverte
klassene.
6Arv
- En subklasse arver ikke-private medlemmer fra
superklassen. - Eksempel på konsekvenser Til et objekt av
klassen Student kan en klient sende følgende
meldinger - finnFnr()
- finnNavn()
- finnAdresse()
- finnStudnr()
Person
-fnr -navn -adr
finnFnr finnNavn finnAdresse
Ansatt
Student
Gjør oppgaven side 364.
-studnr
-lønnstrinn
finnStudnr
finnLønnstrinn
7Vis programliste 10.1 side 365-366.
- Merk forskjellen mellom bruk av super for kall på
konstruktører og kall på metoder - I en konstruktør må et eventuelt kall på super
være første setning. - Kallet spesifiserer hvilken konstruktør som skal
brukes i klassen rett over i klassetreet. - Eksempel super(startFnr, startNavn, startAdr)
- super kan brukes som kvalifikator for å skille
mellom arvede metoder og metoder med samme navn
deklarert i den klassen der vi er. - Eksempel super.toString()
8Hva med dataene i superklassen?
Et objekt av klassen Student har også
objektvariablene fra Person (fødselsnummer,navn
og adresse) inne i seg, men de kan bare nås via
metoder arvet fra Person.
kun tilgjengelig via finn-metoder
finnFnr()finnNavn() finnAdresse() finnStudnr()
12106078756L Ole Pettersen Storgt 3, 7001
Trondheim 1234567L
privat i klassen Student
Student studenten new Student(12106078756L,
"Ole Pettersen", "Storgt 3, 7001 Trondheim",
1234567L)
meldinger som kan sendes til studentobjektet
9Polymorfi
Person personer new Person3 personer0
student1 // objekt av klassen
Student personer1 læreren // objekt av
klassen Ansatt personer2 student2 // objekt
av klassen Student
- Polymorfi mangeformet, som opptrer i mange
former. - Polymorfi gjør det mulig å håndtere objekter av
forskjellige klasser under ett. - Vi har samlet objekter i en tabell Personer.
- Sender samme melding til alle objektene, de
tolker den forskjellig avhengig av hvilken klasse
de tilhører.
for (int i 0 i lt personer.length i) //
sender samme melding til alle objektene
System.out.println(personeri.toString())
10Gyldige tilordninger mellom referanser og objekter
12106078756L "Ole Pettersen" "Storgt 3,
7001 Trondheim" 1234567L
studentobjekt
Student enStudent
ansattobjekt
5107078056L "Hanne Hansen" "Storgt 13,
7001 Trondheim40
Ansatt enAnsatt
personobjekt
12106078756L "Ola Nordmann" "4567 Heia"
Person enPerson
Gjør oppgavene side 372.
11Abstrakte klasser
- Formlene for å regne ut arealet er forskjellig
for sirkel, kvadrat og trekant. - Men arealet kan beregnes for alle typer figurer.
- Metoden finnAreal() er polymorf ( mangeformet,
som opptrer i mange former). - Metoden er abstrakt i klassen Figur (ikke mulig å
finne en formel som gjelder for alle figurer). - Klassen er abstrakt fordi den inneholder en
abstrakt metode. - Det er ikke mulig å lage objekter av en abstrakt
klasse.
Figur
finnAreal
- En subklasse må implementere metoden for at det
skal være mulig å lage objekter av subklassen.
Klassen blir konkret. - At metoden står i klassen Figur forteller at vi
kan sende meldingen finnAreal() til alle objekter
som tilhører konkrete subklasser av Figur.
Kvadrat
Sirkel
Trekant
-grunnlinje -høyde
-radius
-side
finnGrunnlinje finnHøyde finnAreal
finnRadius finnAreal
finnSide finnAreal
Vis programliste 10.3, side 374-376Gjør
oppgavene side 376-377.
12Hva hvis polymorfi ikke hadde eksistert?
- Hva gjør polymorfien for oss?
- I det siste eksemplet lar den oss håndtere ulike
typer geometriske figurer under ett. - Vi sender en melding til et objekt som tilhører
en subklasse av Figur. - Objektet vet selv hvordan arealet skal regnes ut.
- Hva hvis objektet ikke selv visste hvilken formel
som skulle brukes? - Da måtte vi bruke if-else-if, omtrent slik
- if (figur instanceof Sirkel)
- ... formel for å beregne arealet av en
sirkel -
- else if (figur instanceof Kvadrat)
- ... formel for å beregne arealet av et
kvadrat - else
- ... formel for å beregne arealet av en
trekant -
- Tenk deg om en gang til dersom du tror at du
trenger å bruke instanceof kombinert med en
if-else-if-else-sekvens. - Du bør da vurdere om det er bedre å lage en
abstrakt metode i en felles superklasse for de
involverte klassene, og så la hver enkelt klasse
få sin egen implementasjon av metoden
13Når har vi behov for å bruke operatoren
instanceof?
- Vi trenger å bruke instanceof i i de tilfellene
der vi skal sende melding til kun en del av et
subtre. - Vi lager følgende objekter
- A objekt1 new C()
- A objekt2 new E()
- Vi kan trygt sende meldingen metode1() til begge
objektene - objekt1.metode1()
- objekt2.metode1()
- Meldingen metode2() kan vi bare sende til
subklasser til klassen B - if (objekt1 instanceof B)
- B etObjekt (B) objekt1
- etObjekt.metode2()
metode1() abstrakt i A
A
metode2() abstrakt i B
D
C
B
F
E
metode1() implementert her
metode2() implementert her
Gjør oppgaven side 379-380.
14Tilgangsmodifikatorer
- Definisjonsområdet til et navn er den delen av
programmet der navnet kan brukes uten at det må
kvalifiseres. - Tilgjengeligheten til et navn utenfor
definisjonsområdet er bestemt av om det står
private, public, protected eller ingenting foran
navnet (ingenting package). - Klasser
- Alle klasser vi har laget hittil, unntatt
appletene, har vært tilgjengelig kun i den pakken
der de var deklarert. - Appletene har hatt public foran seg. De er
tilgjengelig fra overalt.
- Medlemmer og konstruktører
- private int antall // privat
- protected int finnMinsteVerdi() //
tilgjengelig fra samme pakke// og fra subklasser
(under // bestemte betingelser) - public int finnAntall // offentlig
- int finnHemmeligNummer() // pakketilgang
- Klassetilgang overstyrer medlems/konstruktør-tilga
ng - Eksempel For at et medlem (en konstruktør) skal
være offentlig tilgjengelig må både medlemmet
(konstruktøren) og klassen det tilhører være
deklarert public.
15Tilgjengeligheten til konstruktører og medlemmer
deklarert i klassen C
pakke A
pakke B
klasse C
subklasse til klasse C
private
package
protected
public
) package betyr ingen tilgangsmodifikator
16Anbefalt bruk av tilgangsmodifikatorer
- Objektvariabler og klassevariabler er alltid
private. - Konstanter er vanligvis offentlige, men kan være
private dersom de ikke er av interesse for andre
enn klassen selv. - Konstruktører er vanligvis offentlige.
- Metoder er vanligvis private eller offentlige.
- Konstruktører og metoder kan være beskyttede
dersom det ikke har noen mening å bruke dem
utenfor subklasser. - Klasser har i utgangspunktet pakketilgang (ingen
tilgangsmodifikator). Dette begrenser også
tilgangen til offentlige konstruktører og
medlemmer i klassen. Klasser som skal tas i bruk
generelt, gjøres offentlige og legges i en
navngitt pakke. Da vil automatisk alle offentlige
konstruktører og medlemmer også bli offentlige.
17Oppussingseksemplet med mange flater og mange
typer materialer
Flate
Materiale
-navn frozen -lengde frozen -bredde frozen
Oppussingsprosjekt
navn String frozen
settMateriale( nyttMateriale
Materiale) finnMateriale() finnAreal() finnOmkr
ets()
1
bruker
registrerNyFlate( nyFlate Flate) finnFlate(nav
n String) finnAntFlater() finnFlate(indeks
int) registrerNyttMateriale( nyttMateriale
Materiale) finnMateriale(navn String) finnAntMate
rialer() finnMateriale(indeks int) finnTotalpris(
)
består av
1
Materiale
1
-navn frozen -pris frozen
trenger
finnTotalpris(enFlate Flate) finnMaterialbehov(
enFlate Flate)
Maling
Belegg
Tapet
-breddePåBelegg frozen
-lengdePrRull frozen -breddePrRull frozen
-antStrøk frozen -antKvmPrLiter frozen
finnMaterialbehov( enFlate Flate)
finnMaterialbehov( enFlate Flate)
finnMaterialbehov( enFlate Flate)
Vis programliste 10.5, side 385-386.
18Oppussingseksemplet med mange flater og mange
typer materialer, programmering
- Utsnitt fra kapittel 9
- class Oppussingsprosjekt
- private String navn
- private ArrayList ltFlategtalleFlater
new ArrayListltFlategt() - private ArrayList ltMalinggtalleMalingstyper
new ArrayListltMalinggt() - public Maling registrerNyMaling(
Maling nyMalingstype) - String navnet nyMalingstype.finnNavn()
- Maling denne finnMaling(navnet)
- if (denne null)
- alleMalingstyper.add(nyMalingstype)
- return nyMalingstype
-
- else return denne
-
- Nå, i kapittel 10
- class Oppussingsprosjekt
- private String navn
- private ArrayListltFlategt alleFlater
new ArrayListltFlategt() - private ArrayListltMaterialegt alleMaterialtyper
new
ArrayListltMaterialegt() - public Materiale registrerNyttMateriale(
Materiale nyMaterialtype) - Materiale denne finnMateriale(nyMaterialtype
.finnNavn()) - if (denne null)
- alleMaterialtyper.add(nyMaterialtype)
- return nyMaterialtype
-
- else return denne
-
En referanse til Materiale kan settes til å peke
til et objekt av en hvilken som helst subklasse.
Vårt nye program kan håndtere mange forskjellige
materialer, til tross for få endringer i forhold
til programmet i kapittel 9. Vi utnytter arv og
polymorfi.
19Arv i to nivåer
Materiale
-navn -pris
finnNavn() finnPrisPrEnhet() finnTotalpris(enFl
ate Flate) finnMaterialbehov(enFlate Flate)
Belegg2
Tapet
Maling
-breddePåBelegg
-lengdePrRull -breddePrRull
-antStrøk -antKvmPrLiter
finnBredde() finnMaterialbehov(enFlate Flate)
finnAntStrøk() finnAntKvmPrLiter()finnMaterial
behov( enFlate Flate)
finnLengde() finnBredde() finnMaterialbehov(
enFlate Flate)
AnnenSortBelegg
ForsteSortBelegg
Vis programliste 10.6 side 389-390.
finnTotalpris(enFlate Flate) finnMaterialbehov(
enFlate Flate)
20Modifikatoren abstract
- Abstrakt klasse
- abstract class Materiale .osv.
- kan ikke lage objekter av en abstrakt klasse
- behøver ikke inneholde eller arve abstrakte
metoder - kan inneholde både abstrakte og konkrete metoder
- Abstrakt metode
- abstract metodehode
- En klasse som arver, eller selv deklarerer en
abstrakt metode, må deklareres som abstrakt.
21Det reserverte ordet super
- super kan brukes på to måter
- I en konstruktør for å anrope konstruktøren rett
over i klassetreet, eksempel - public AnnenSortBelegg(String startNavn, double
startPris, int startBredde) - super(startNavn, startPris, startBredde)
-
- Kallet på super() må være første setning i
konstruktøren. - Argumentlisten til super() må være i samsvar med
parameterlisten til en konstruktør i
superklassen. - I en hvilken som helst metode kan vi bruke super
som kvalifikator for å henvise til et skjult
eller erstattet navn i en superklasse, eksempel - public double finnMaterialbehov(Flate enFlate)
- double grunnBehov super.finnMaterialbehov(en
Flate) - return grunnBehov materialTillegg
-
- Vi kan ikke skrive super.super() eller lignende
for å anrope konstruktør eller metode på mer enn
ett nivå over i klassetreet.
22Konstruktører
- Dersom vi ikke kaller en bestemt konstruktør i
den direkte superklassen ved å anrope super(),
vil standardkonstruktøren i superklassen anropes.
- Dersom denne ikke eksisterer, vil kompilatoren gi
en feilmelding. - Dersom det ikke har mening å lage objekter av en
klasse, kan det forhindres på to måter - Lag klassen abstrakt. Dette brukes dersom klassen
har eller kan ha subklasser. - Lag alle konstruktører private. Dette brukes
dersom klassen ikke kan ha subklasser (den er
final, se nedenfor).
23Referanser og casting
Person
Ansatt
Student
- En referanse til en klasse kan settes til å peke
til objekter av en subklasse til klassen. Den kan
ikke settes til å peke til objekter av en
superklasse. - Person personen new Student(12106078756L, "Ole
Pettersen", "Storgt 3, 7001 Trondheim",
1234567L) // ok - Ansatt læreren new Student(12106078756L, "Ole
Pettersen", "Storgt 3, 7001 Trondheim",
1234567L) // ikke ok - Ansatt læreren new Person(12106078756L, "Ole
Pettersen", "Storgt 3, 7001 Trondheim") //
ikke ok - Anta at vi har en referanse til et objekt.
- Referansen kan castes til den klassen objektet
tilhører, eller til superklasser av denne
klassen. - Det er ikke tillatt å caste referansen til en
subklasse av den klassen som objektet tilhører. - Ugyldig casting gir ClassCastException.
- Object etObjekt new Student(12106078756L, "Ole
Pettersen", "Storgt 3, 7001 Trondheim",
1234567L) // ok - Student enStudent (Student) etObjekt
- Ansatt enAnsatt (Ansatt) etObjekt // ikke ok
- Person enPerson (Person) etObjekt // ok
24Modifikatoren final
- final forhindrer subklassing og erstatning.
- En final metode kan ikke erstattes eller skjules
- public final double finnBredde()
- return breddePåBelegg
-
- Det er ikke mulig å subklasse en final klasse
- final class AnnenSortBelegg extends Belegg2
- .osv.
25Å erstatte eller skjule et navn
- Å erstatte en arvet objektmetode
- Hvis en klasse deklarerer en objektmetode, vil
denne deklarasjonen erstatte en eventuell arvet
metode med samme signatur. - Kompilatoren gir feilmelding dersom returtypen
ikke stemmer og/eller tilgangsnivået er mindre
strengt enn i den erstattede metoden. - En objektmetode kan ikke erstatte en arvet
klassemetode.
class AnnenSortBelegg extends Belegg2 ..
public double finnMaterialbehov(Flate enFlate)
double grunnBehov super.finnMaterialbehov(enF
late) return grunnBehov materialTillegg
Denne metoden erstatter den arvede utgaven av
finnMaterialbehov()
Her refererer vi til den erstattede metoden.
Vi kan skjule arvede variabelnavn og
klassemetoder. Dette brukes ikke i denne boka.
26Interface
Repetisjon fra kapittel 9.
- Et interface er en samling med metodehoder.
- En klasse kan velge å implementere et interface.
Den må da programmere alle metodene i interfacet.
- Eksempel på interface
- public interface ComparableltTypegt // tilhører
pakken java.lang - public int compareTo(Type obj)
-
- Eksempel på klasse som implementerer interfacet
- class Flate implements ComparableltFlategt
- ... objektvariabler ...
- public int compareTo(Flate denAndreFlaten)
- double areal1 finnAreal()
- double areal2 denAndreFlaten.finnAreal()
- if (Math.abs(areal2 - areal1) lt toleranse)
return 0 - else if (areal1 lt areal2) return -1
- else return 1
-
- ... andre metoder i klassen ...
-
27Å lage egne interface
Tilgangsmodifikator public eller ingenting
(pakketilgang)
interface SammenligningsbarltTypegt boolean
størreEnn(Type obj) boolean mindreEnn(Type
obj) boolean lik(Type obj)
public abstract underforstått for metoder
Et interface er abstrakt, vi kan ikke lage
objekter av et interface.
28Implementasjon av interfacet
class FireSifretHeltall implements
SammenligningsbarltFireSifretHeltallgt private
static final int min 1000 private static
final int maks 9999 private int verdi
public FireSifretHeltall(int startVerdi) if
(startVerdi lt min) verdi min else if
(startVerdi gt maks) verdi maks else verdi
startVerdi public int finnVerdi()
return verdi public boolean
størreEnn(FireSifretHeltall tall) return
(verdi gt tall.finnVerdi()) public boolean
mindreEnn(FireSifretHeltall tall) return
(verdi lt tall.finnVerdi()) public boolean
lik(FireSifretHeltall tall) return (verdi
tall.finnVerdi())
Klassen må implementere alle metodene i
interfacet Sammenligningsbar, for at klassen ikke
skal bli abstrakt.
29Bruk av klassen FireSifretHeltall
Utskrift / 1000 1700 9999 false true false /
class EksempelInterface public static void
main(String args) FireSifretHeltall tall1
new FireSifretHeltall(700)
FireSifretHeltall tall2 new FireSifretHeltall(17
00) FireSifretHeltall tall3 new
FireSifretHeltall(70000) System.out.println(t
all1.finnVerdi()) System.out.println(tall2.fi
nnVerdi()) System.out.println(tall3.finnVerdi
()) System.out.println(tall1.størreEnn(tall2)
) System.out.println(tall1.mindreEnn(tall2))
System.out.println(tall1.lik(tall2))
- En referanse av en interface-type kan referere
til objekter som tilhører en klasse som
implementerer interfacet - Sammenligningsbar tall1 new FireSifretHeltall(70
0) - Sammenligningsbar tall2 new FireSifretHeltall(17
00) - Vi kan nå bare sende meldinger deklarert i
interfacet til objektet - System.out.println(tall1.størreEnn(tall2)) //
ok - System.out.println(tall1.finnVerdi()) // ikke
ok