Kurt Nørmark ©
Department of Computer Science, Aalborg University, Denmark
September 2001
Abstract Previous lecture Next lecture Index References Contents | I denne lektion studerer vi objekt-orienteret programmering, specielt som det tager sig ud i Java. En del af vore observationer og sondringer er dog også generelle. Sidst i lektionen ser vi endvidere på nogle af de praktiske aspekter af Java programmeringsomgivelsen, herunder organiseringen af Java klasser i filer, kataloger og såkaldte 'packages'. Objekt-orienteret programmering i Java fortsættes i næste lektion |
Klasser |
Eksempel: Klassen Konto Slide Note Contents Index References Speak | Vi ser her på et eksempel på en klasse i Java, som illustrerer en række forskellige af de emner, vi ser på i denne lektion |
Program: Java klassen Konto.
Vi vil benytte denne simple klasse som et gennemgående eksempel i denne lektion.
En af opgaverne ved øvelserne til denne lektion vil endvidere tage udgangspunkt i denne
klasse. Vi vil forklare de enkelte bestanddele af klassen i takt med, at vi introducerer
de forskellige udtryksmuligheder i Java's klassebegreb |
|
Exercise 2.1. Modifikationer af Konto klassen | Denne opgave tager udgangspunkt i programmet Babybank som vi allerede har set på ved forelæsningen. Lav følgende ændringer i programmet:
således en konto med 60 kroner. Det er tilladt at ændre på de private egenskaber af klassen Konto, men ingen offentlige egenskaber må ændres! I har behov for at bruge Arrays (eller lignende) i denne opgave. Vi har endnu ikke set på dette emne i stor detalje, men jeg har lavet et kort demonstrationsprogram, som viser hvordan man bruger arrays. Vi vender lidt senere i kurset tilbage til arrays og lister. |
Opgave: Klassen Spillekort Slide Note Contents Index References Speak | På denne side lægger vi op til en opgave om repræsentation af Spillekort |
Exercise 2.2. Klassen Spillekort | Et kortspil består af 52 kort fordelt på fire farver (betegnet
hjerter, ruder, klør og spar) og 13 værdier (fra 1 til 10 samt
knægt, dronning og konge). Skriv en klasse Spillekort, som repræsenterer et enkelt kort i et kortspil. Datarepræsentation skal være privat i klassen. Vi ønsker at bruge instanser af Spillekort i spil, hvor kortene skal sammenlignes størrelsesmæssigt med andre kort. Derfor skal der være operationer størreEnd, ligMed og mindreEnd i klassen. Sammenligningen af to kort beror udelukkende på kortets værdi; farven spiller altså ingen rolle. Vi ønsker følgende orden, hvor to er mindst og es er størst: 2 < 3 < ... < 9 < 10 < knægt < dronning < konge < 1 Redefiner metoden toString fra Object til at returnere en tekst streng, som identificerer et spillekort entydigt i forhold til de andre spillekort, f.eks. 'klør 5' og 'spar es'. Programmer en eller flere konstruktorer i klassen Spillekort, således at instantiering af et helt kortspil (52 kort) bliver så let som mulig (se herefter). Skriv dernæst et program, som konstruerer et komplet spil kort bestående af 52 kort. Med andre ord, ønsker vi at programmet laver 52 objekter af klassen Spillekort. Vi ønsker ikke at skulle skrive 52 kald af new Spillekort(...) efter hinanden med forskellige parametre; det vil naturligvis være særdeles hensigtsmæssigt at kunne foretage instantieringen i en løkke. En forudsætning for at kunne gøre dette er en hensigtsmæssigt valgt Spillekort konstruktor. Organiser kortspillet i et array. |
Klasser i Java Slide Note Contents Index References Speak | Vi vil nu se klasser's syntaktiske egenskaber i Java |
|
Syntax: Vi viser her en typisk syntaktisk opbygning af en klasse. Klassen har et navn, og den indeholder erklæringer af data, konstruktorer og metoder. Rækkefølgen af disse bestanddele er ikke påbudt, men blot typisk. |
|
En klasse kan have andre egenskaber, f.eks nedarvning og
synligheds angivelser af variable og metoder, som udmønter sig i yderligere syntaks. |
Instansvariable Slide Note Contents Index References Speak | Instansvariable repræsenterer tilstanden i de objekter, der instantieres ud fra klassen. I litteraturen om objekt-orienteret programmering er der mange forskellige betegnelser for disse: Attributter, felter, data members. Vi vælger at bruge Smalltalk's terminologi, som er enkel og præcis: Der er tale om variable i gængs forstand, som er knyttet til individuelle instanser af en klasse. Som kontrast vil vi senere se på 'klassevariable' |
The concept instansvariabel: En instansvariabel er en dataerklæring i en klasse. Hvert objekt, som instantieres ud fra klassen, har egne versioner af instansvariablene |
Program: Klassen Konto har tre instansvariable: rentesats, navn og saldo. |
|
Figure. Vi ser tre objekter af typen Konto. Læg specielt mærke til de individuelle værdier af objekternes instansvariable. Altså, i ét Konto objekt er balancen 100.0, i et andet 300.0, osv. | ![]() |
Metoder i Java Slide Note Contents Index References Speak | Metoderne i Java svarer til procedurer og funktioner i konventionelle programmeringssprog. Som vi har set tidligere er det sådan i Java, at enhver procedure eller funktion er en metode i en klasse. Metoderne implementerer adfærd i klasserne. |
Syntax: En metode skal have en returtype, et navn, en (evt. tom) parameterliste og en krop. Kroppen er syntaktisk set en blok. Før disse bestanddele listes en række metodegenskaber (også kaldet 'modifiers'), eksempelvis synlighedsegenskaber |
|
The concept metode: En metode er en procedure eller funktion, som påvirker eller aflæser klassens tilstand | Metoder svarer til procedurer eller funktioner. En 'god' metode vil altid relatere sig til de data, som klassen indkapsler. Procedurer har ingen naturlig returværdi; Derfor angives denne som void. |
|
|
Eksempler på metoder i klassen Konto Slide Note Contents Index References Speak | Vi ser her nærmere på et par metoder fra klassen Konto, som blev vist i sin helhed ovenfor. |
Program: Metoden balance er parameterløs, og den returnerer blot instansvariablen saldo.
Bemærk, at returtypen double svarer til saldo's type. |
|
Program: Metoden hæv er en procedurer, som ændrer tilstanden af en konto. Derfor er returtypen void.
Bemærk, at returneringen er implicit, ved enden af metodens krop. |
|
|
Objektskabelse og nedlæggelse |
Generelt om skabelse af objekter Slide Note Contents Index References Speak | Et objekt kan skabes på to forskellige måder: Enten ved at skabe objektet med klassen som forskrift, eller ved at skabe objektet med et andet og eksisterende objekt som forskrift. |
|
Kloning er et biologisk inspireret ord, som betyder at frembringe individer med samme arveanlæg som det oprindelige. I Java er kloning, via metoden 'clone', et relativ omstændeligt forehavende, som vi ikke vil gå mere i detaljer med i denne lektion. |
|
Generelt om nedlæggelse af objekter Slide Note Contents Index References Speak | Man skulle måske tro, at objektnedlæggelse er af mindre betydning end objektoprettelse. Men dette er ikke tilfældet. Det er ofte meget vigtigt at skaffe sig af med unyttige objekter, idet vi ellers på et eller andet tidspunkt løber tør for lager (uanset hvor mange Mbyte vi end har). Det er endvidere helt afgørende for et program, at objekter ikke nedlægges for tidligt. |
|
I forbindelse med eksplicit sletning af et objekt er faren, at vi sletter objektet 'for tidligt'. Hvis vi efter sletningen forsøger at tilgå objektet via en reference til det, opstår der en 'grim' fejl (køretidsfejl) Implicit og automatisk sletning af objekter kaldes ofte for garbage collection. Når et programmeringssprog understøtter garbage collection fritages programmøren for en væsentlig byrde, idet han eller hun ikke skal bekymre sig om, hvornår 'der skal siges farvel' til objekterne |
Skabelse af objekter i Java Slide Note Contents Index References Speak | Vi vil nu studere objektskabelse ved klasse instantiering af Java klasser i betydelig detalje. Vi vil tale om både instantiering og initialisering. Emnet er meget vigtigt når vi bedriver objekt-orienteret programmering. Vi starter derfor med at repetere instantiering og initialisering i forhold til første lektion i kurset. |
The concept instantiering: Instantiering er processen hvorved der allokeres lager til et 'tomt' objekt. | At et objekt er 'tomt' betyder, at der ikke findes veldefinerede værdier i objektets instansvariable. Objektet er en 'hul skal' omkring et et udefineret indhold | |
The concept initialisering: Initialisering er processen hvorved der tilskrives fornuftige startværdier til objektets instansvariable |
|
Kloning af objekter i Java med clone() metoden, som hører til i Java's mest generelle klasse Object, er besværlig at anvende. Vi skal ikke her komme ind på alle detaljer. Emnet vil blive behandlet i forbindelse med nedarvning. Blot kan vi notere os, at klon-dygtige objekter skal være instanser af klasser, der er programmeret eksplicit med henblik på cloning. Man kan ikke umiddelbart sende beskeden clone til et vilkårligt objekt. Vi henviser iøvrigt til hosstående reference om cloning i Java, som peger længere frem i noterne. |
|
Nedlæggelse af objekter Java Slide Note Contents Index References Speak | Nedlæggelse af objekter i Java er relativ ukompliceret, idet Java anvender automatisk garbage collection |
|
Detaljer om nedlæggelse af objekter Java Slide Note Contents Index References Speak | Her ser vi på detaljer om finalization i Java. I lang de fleste tilfælde skal man ikke bekymres sig om dette. |
|
I princippet - men næppe i praksis - kan finalize metoden etablere en reference til det objekt, der er tæt på at blive nedlagt. Det vil forårsage, at objektet alligevel ikke nedlægges. |
|
Objekter og referencer Slide Note Contents Index References Speak | Ethvert objekt i Java tilgås via en reference. Vi vil her se nærmere på objekter i forhold til referencer, og vi vil også diskutere 'objekt navne' og 'objekt variable' |
|
Figure. To objekter: en bankkonto og en streng. Bankkontoen refereres af to forskellige variable. Streng objektet refereres ikke fra en variabel, men fra bankkontoen | ![]() |
Konstruktorer i Java Slide Note Contents Index References Speak | Initialisering af et nyskabt Java objekt sker gennem en såkaldt konstruktor |
The concept konstruktor: En konstruktor er en procedure som har til opgave at initialisere instansvariablene af et nyskabt objekt |
|
|
|
Konstruktor i klassen Konto Slide Note Contents Index References Speak |
Program: Vi ser her en konstruktor i klassen Konto, som initialiserer instansvariablene. Initialiseringen foregår
i dette tilfælde dels ud fra en medsendt parameter, dels ved et fast assignment.
Herunder viser et programfragment, hvor vi laver to Konto objekter.
Bemærk, at det viste fragment er to erklæringer med initialiseringsdele. |
|
Program: Vi ser her et programfragment, hvor vi laver to Konto objekter.
Bemærk, at det viste fragment er to erklæringer med initialiseringsdele. |
|
Konstruktorer i klassen Point Slide Note Contents Index References Speak |
Program: En klasse Point med flere konstruktorer.
Klassen Point har tre konstruktorer, som alle naturligvis hedder Point.
Typen af de formelle parametre gør det muligt at kende forskel på disse.
Læg mærke til at Point() konstruktoren kalder this(0.0, 0.0), hvilket
kalder Point(double,double).
Det er ofte nyttigt på denne måde at lade
specialiserede og begrænsede konstruktorer kalde mere generelle konstruktorer.
Konstruktoreren, som tager et Point objekt som parameter kaldes en kopierende konstruktor,
idet den laver en kopi af et allerede eksterende Point objekt. Også denne konstruktor
kalder Point(double,double).
I 'hovedprogrammet' vist herunder erklærer vi et antal punkter, som konstrueres ved brug af konstruktorerne. |
|
Program: En anvendelse af de fire konstruktorer vist ovenfor.
I 'hovedprogrammet' erklærer vi fire punkter, som konstrueres ved brug af de fire forskellige konstruktorer. |
|
|
Værdier i forhold til objekter Slide Note Contents Index References Speak | Man kan være fristet til at tænke på 'alt som objekter'. Her vil vi introducere en skelnen mellem 'værdier' og 'objekter', som er ganske vigtig når man programmerer i Java. |
The concept værdi: En værdi er et dataelement uden identitet, og uden mulighed for at ændre tilstand | Værdier er typisk repræsentationer af matematiske størrelse, f.eks. tal, sandhedsværdier og tegn. Vi kan ikke ændre et tal, f.eks. 7, til at være et andet tal. | |
The concept objekt: Et objekt er et indkapslet dataelement med identitet, tilstand og adfærd | Et objekt er repræsenteret af dets instansvariable. Objektet har identitet uafhængig af instansvariablenes værdier. Når først objektet er skabt er det unik igennem hele dets levetid, og der vil aldrig blive skabt et objekt med samme identitet igen! Objektets tilstand kan ændres uden på nogen måde at ændre ved objektets identitet. Objektets adfærd udgøres af de metoder, der er defineret i objektet's klasse |
I objekt-orienteret programmering er det muligt at simulere objekter, der opfører sig som værdier Når vi ønsker at opfatte et objekter som en værdi må vi forhindre mutation (tilstandsforandring) af objektet. Når eller hvis vi forsøger at ændret på et sådan objekts tilstand vil det afstedkomme skabelsen af et nyt objekt, i stedet for forandringen af det eksisterende objekt. Et andet aspekt af simuleringen kan være eksplicit at forhindre skabelsen af to objekter, der repræsenterer den samme værdi. Dette kan ske ved umiddelbar før instantieringen af et objekt at checke hvorvidt vi allerede én gang har skabt et objekt med de 'samme' egenskaber |
|
|
Tekststrenge i Java Slide Note Contents Index References Speak | Vi ser her - i forbifarten - på Strenge. Vores motivation på dette sted er at strenge opfører sig som værdier i Java. |
|
Vi kan ikke ændre på tegnene i en streng. Vi siger ofte, at strengen er ikke-mutérbar. Det betyder at hvis en bestemt string, f.eks. "pip" bliver brugt mange steder i et program kan vi nøjes med at allokere én instans. Vi behøver ikke at frygte at et hjørne i programmet ændrer på tegnene i "pip", og dermed skaber kaos mange andre steder i programmet hvor vi ikke forventer denne ændring Vi ser senere i denne lektion på lighed mellem objekter, og herunder på metoden equals |
|
Lighed |
Generelt om lighed mellem objekter Slide Note Contents Index References Speak | Vi ser nu på lighedsbegrebet og objekter. Lighed af værdier (tal, char, boolean) er uproblematisk, idet det er veldefineret hvad det vil sige at to tal, tegn, eller boolske værdier er ens eller ej. Så her koncentrerer vi os om lighed mellem objekter |
|
Når vi taler om den 'mest diskriminerende form for lighed' hentyder vi til den ækvivalensrelation, som skaber de fleste klasser i en klassedelning. Udtrykt mindre matematisk, kan vi sige at denne form for lighed skelner flest mulige objekter fra hinanden. Et objekt vil kun være lig med sig selv. |
|
Eksempel på reference lighed Slide Note Contents Index References Speak |
Figure. x og y er 'reference equal' idet x og y peger på ét og samme objekt | ![]() |
Eksempel på 'shallow' lighed Slide Note Contents Index References Speak |
Figure. x og y er 'shallow equal'. De to objekter refereret af x og y har instans variable, som parvis er lig med hinanden pr. reference lighed | ![]() |
Eksempel på dyb lighed Slide Note Contents Index References Speak |
Figure. x og y er 'deep equal'. Referencerne x og y refererer objektnetværk, som - i dybden - er strukturelt ens. Hvor der forekommer instansvariable som indeholder værdier, er disse parvis ens | ![]() |
Lighed i Java Slide Note Contents Index References Speak |
I forbindelse med muligheden for at redefinere metoden equals: Vi så tidligere i denne lektion af klassen String har redefineret metoden equals med det formål at gøre to strenge lig med hinanden hvis de indeholder de samme tegn (i samme rækkefølge). |
|
Denne observation holder iøvrigt generelt når man lave objekt-orienteret programmering, Der er mange varianter af lighed som ikke falder ind under de tre former for lighed vi har identificeret ovenfor. Det er nødvendigt - klasse for klasse - at angive hvad det vil sige, at to instanser af klassen er ens |
Exercise 2.3. Lighed mellem bankkonti | I denne opgave arbejder vi videre på babybank som tidligere i denne lektion har været under behandling i en opgave. Tilføj en metode equals, der angiver at to bankkonti er ens hvis følgende betingelser er opfyldt:
Lav en klasse med en main metode, som laver to konti. Prøvekør programmet med det formål at teste om equals virker efter specifikationen. |
Mønster for equals i Java Slide Note Contents Index References Speak | Her viser vi en typisk redefinition af equals(Object other) i Java. |
|
Program: En equals metode fra klassen EqualsDemo som redefinerer equals fra Object.
Bemærk if-then-else strukturen, som tester om other er af samme type som det nuværende objekt.
Bemærk også at vi bliver nødt til at 'caste' other til EqualsDemo for at trække tilstanden ud af objektet.
Bemærkt endelig, at vi kan tilgå state i other på trods af at state er private.
|
|
Emnet fortsættes i en efterfølgende lektion |
Chapter 2: Objekt-orienteret programmering i Java, del 1
Course home Author home About producing this web Previous lecture (top) Next lecture (top) Previous lecture (bund) Next lecture (bund)
Generated: March 31, 2008, 12:08:02