det som skiljer objektorienterad programmering, oop, från den traditionella, imperativa...

39
OOP - OBJEKTORIENTERAD PROGRAMMERING Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen - och hittills har vi programmerat även Java enligt denna syn - är det processer som är det viktiga. När vi lär oss att programmera, ska vi först designa en algoritm, som berättar hur uppgiften skall lösas, vilka instruktioner datorn skall utföra och i vilken ordning, för att få fram det önskade resultatet. Inom imperativ programmering är det alltså processen som är det centrala, data något sekundärt, det som påverkas av processen. Ex. anta att vi ska designa ett nytt datasystem för ett bibliotek. Det första vi frågar oss är vilka processer som äger rum i biblioteket, dvs. vilka processer som ska ingå i det nya systemet. Vi kommer kanske fram till följande lista: $ att låna ett exemplar av en bok $ att returnera ett exemplar $ att reservera en bok (obs! inte ett exemplar - varför?) $ att skicka kravbrev på ett exemplar $ att registrera en ny kund $ att söka information om en bok Alla dessa punkter är processer - att låna, att returnera, att reservera. Inom denna världsbild består den aktiva världen, det som vårt nya datasystem skall reflektera, av processer. De som påverkas av processerna, kunderna, exemplaren, kravbreven, böckerna, ses som objekt, data som påverkas av processerna. Processerna är det primära, data något sekundärt. Java II med Annamari, närpass 3: Objektorienterad design 1

Upload: others

Post on 06-Mar-2020

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

OOP - OBJEKTORIENTERAD PROGRAMM ERING

Det som skilj er objektorienterad programmering, OOP, från dentraditionella, imperativa programmeringsstilen, är vär ldssynen. Inom denimperativa traditionen - och hittill s har vi programmerat även Java enligtdenna syn - är det processer som är det viktiga. När vi lär oss attprogrammera, ska vi först designa en algoritm, som berättar hur uppgiftenskall lösas, vilka instruktioner datorn skall utföra och i vilken ordning, föratt få fram det önskade resultatet. Inom imperativ programmering är detalltså processen som är det centrala, data något sekundär t, det sompåverkas av processen.

Ex. anta att vi ska designa ett nytt datasystem för ett bibliotek. Det första vifrågar oss är vilka processer som äger rum i biblioteket, dvs. vilkaprocesser som ska ingå i det nya systemet. Vi kommer kanske fram tillföljande lista:

$ att låna ett exemplar av en bok$ att returnera ett exemplar$ att reservera en bok (obs! inte ett exemplar - varför?)$ att skicka kravbrev på ett exemplar$ att registrera en ny kund$ att söka information om en bok

� ��

Alla dessa punkter är processer - att låna, att returnera, att reservera. Inomdenna världsbild består den aktiva världen, det som vårt nya datasystemskall reflektera, av processer. De som påverkas av processerna, kunderna,exemplaren, kravbreven, böckerna, ses som objekt, data som påverkas avprocesserna. Processerna är det pr imära, data något sekundär t.

Java II med Annamari, närpass 3: Objektorienterad design 1

Page 2: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

Inom OOP är synen på världen radikalt annorlunda. Grundtanken inomOOP är att vi, normala människor som inte ännuhar blivit hjärntvättade avdatalogistudier, strukturerar världen helt annorlunda. När vi kommer in inett bibliotek så är det ingalunda processerna som vi först fästeruppmärksamhet vid, utan de fysiska objekten: böckerna (eller egentligenexemplaren), människorna (kunderna och personalen), hyllorna. Det är desom intresserar oss: vi vill kanske söka information om en vissbok, ochantingen reservera boken eller låna ut ett exemplar av den, ifall vi hittarett på rätta hyllan. För att hitta den rätta hyllan ber vi kanskebibliotekar ien om hjälp. Observera, att både vi själva och bibliotekarien viber om hjälp räknas här bland de fysiska objekten - inget ill a menat meddet!

När vi då analyserar världen enligt denna programmeringsparadigm, så ärdet objekten som bli r det centrala. Processerna bli r något sekundär t, debli r egenskaper, att r ibut, hos objekten.

Ex. objektet bibliotekskund kan ha följande attribut (egenskaper):

- kundnummer- namn

- adress (så vi vet vart skicka kravbreven) - en lista över innestående lån* att reservera en bok* att låna ett exemplar* att returnera ett exemplar* lista innestående lån* betala böten* utföra en sökning

Jag har markerat med '-' de egenskaper som beskr iver objektet i fråga,och med '* ' de egenskaper som är processer som objektet kan utföra. IJava skulle vi tala om var iabler respektive metoder. Båda dessa kanräknas som attribut; de beskriver objektet i fråga. Terminologin inom OOPär inte enhetlig. Jag ska i fortsättningen kalla dessa för att r ibut respektiveprocesser i allmänhet, var iabler respektive metoder i Java i synnerhet.

Java II med Annamari, närpass 3: Objektorienterad design 2

Page 3: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

Objektet bok skulle kunna ha följande attribut och processer:

- ISBN-numret- namnet- författarens namn- förlaget- tryckort- tryckår- antalet exemplar- reservationslista (en FIFO-kö)* skriva ut första människan på reservationslistan* sätta till en ny reservation i slutet av kön

Ett exemplar av en bok skulle ärva vissa av egenskaperna hos en bok:

- ISBN-numret- namnet- författarens namn- förlaget- tryckort- tryckår

Därutöver skulle varje exemplar till hörande en bok ha vissa egna attribut:

- exemplarnummer* kan utlånas - till vem?* kan förstöras/försvinna* kan returneras

Vi skall diskutera begreppet arv (nedärvning) senare; exemplet ovan skaexempli fiera OOP helt allmänt. Att börja koda ett dylikt bibliotekssystemskulle kräva rätt så avancerade kunskaper i Java och databashantering, såvi ska koda enklare exempel först. Efter att du har tagit kursen i Databasertorde du kunna koda exemplet ovan utan större problem.

Java II med Annamari, närpass 3: Objektorienterad design 3

Page 4: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

EGENSKAPER HOS OOP - ALL MÄN PRESENTATION

De egenskaper som vi skall diskutera nedan gäller allmänt förobjektorienterad design. Vissa av dessa principer kan vi försöka till ämpaäven när vi jobbar med traditionella, imperativa programmeringsspråk somPascal, Modula-2 eller C. De språk som gör anspråk på att vara specielltobjektorienterade, ex. Beta, Eiffel, C++ eller Java, har implementerat(konkretiserat, förverkligat) dessa egenskaper på olika sätt. Här är detalltså frågan om allmänna principer som du kan vänta dig att hittaimplementerade på olika sätt i olika objektorienterade språk. Vi skall försttitta på dessa principer, sedan ska vi se exempel på hur Java harimplementerat dem.

OOP

Java C++ Beta Eiffel ...

Den objektor ienterade vär ldssynen som vi beskrev ovan är gemensamtför alla dessa språk: det centrala är objekten, processerna äregenskaper hos enskilda objekt, något som dessa kan utföra.

Härtill kommer det tre centrala principer:

DATAINKAPSLING (data incapsulation)ARV(NEDÄRVNING) (inheritance)FLERFORMIGHET (polymorphism)

Dessa tre skall förklaras nedan, först allmänt, sedan med Java-exempel.

(Egentligen exempli fierar figuren ovan redan dessa principer: de olikaprogrammeringsmetoderna är inkapslade i dessa olika språk; alla

ärver de vissa principer från OOP, men de implementerar dessa påolika sätt.)

Java II med Annamari, närpass 3: Objektorienterad design 4

Page 5: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

DATAINKAPSLING:

Datainkapsling innebär att man "kapslar in" data och metoder som hör ihop(tänk på hur de olika ingredienserna är inkapslade i medicinkapsyler!).Idén är att sammanhörande data skall kunna hanteras som en enhet, och attutomstående programdelar inte kommer åt dessa delar separat om vi inteuttryckligen önskar det. Många OOP-språk - inklusive Java - har ytterstsofistikerade hierarkier på dylika "kapslar", och ytterst mångskiftanderegler på hur och varifrån deras olika delar kan accesseras - eller inteaccesseras.

I Java har vi ex. paket, klasser, objekt, instanser, metoder osv. som allafungerar som helheter bestående av separata delar. Ofta är det helheten vivill arbeta med, i vissa situationer delarna. I våra Java-exempel brukar viex. importera paketet javagently för att komma åt den extremt nyttigaText -klassen, som i sin tur består av flera användbara metoder för attläsa in och skriva ut olika sorters värden, eller hjälpa ossmed filhantering.Vi behöver bara känna till namnet på metoden och hur vi skall anropa den,och så utförs metoden för oss. Det som vi däremot inte behöver känna tillär hur metoden är implementerad, vilka kommandon den utför. Det enaenda som intresserar oss är resultatet. Det är detta som förstås medinkapsling.

javagently Text * Text.readInt* Text.readDouble* Text.readChar* Text.readString* Text.writeDouble* ...

Om vi tänker på biblioteksexemplet ovan, så skulle både kunden, bokenoch exemplaret vara inkapslade som objekt: inne i detta objekt finns alla deolika attributerna, både de "vanliga" och processerna, som till hör just dettaobjekt. I Java skulle vi kalla ett dylikt objekt för en klass(ex. kund) och deolika verkliga kunderna för instanser av denna klass.

Java II med Annamari, närpass 3: Objektorienterad design 5

Page 6: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

ARV/NEDÄRVNING (INHERITANCE)

Typiskt för OOP är att de olika objekten (eller klasserna, om vi villanvända Javas terminologi) utgör en hierarki.

Ex. Människa

Personalmedlem Studerande

Lektor Professor DI IB

Vi ser av figuren ovan att vi har två sorters människor i vårt system -personalmedlemmar och studerande. Personalmedlemmarna delar sigvidare i lektorer och professorer, och de studerande i DI (blivandediplomingengörer) och IB (blivande filosofie magistrar). I denna ytterstförenklade värld kan vi dock studera begreppet arv riktigt bra: deegenskaper som är gemensamma för alla människor definieras hos objektetmänniska. Både personalmedlemmar och studerande är människor (ävenom det inte allti d känns så ...) och de ärver alla de egenskaper som ärgemensamma för alla människorna, dvs. alla de egenskaper, attribut ochprocesser, som är deklarerade för objektet människa. Men: det finnsegenskaper hos personalmedlemmar, ex. titel, undervisningsskyldighet ochlöneklass, som ingalunda gäller för alla människor. Dessa deklarerasseparat för klassen Personalmedlem. På motsvarande sätt, det finnsegenskaper som är specifika för de studerande, som ex. matrikelnummeroch en lista över avklarade kurser. Dessa deklareras separat för klassenStuderande. Vidare indelas klassen Personalmedlem i lektorer ochprofessorer. Dessa ärver alla de egenskaper som gäller förpersonalmedlemmar (och därvia människor), men kan deklarera sina egna

Java II med Annamari, närpass 3: Objektorienterad design 6

Page 7: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

attribut; för professorsklassen kommer det ex. massor av administrativaskyldigheter och ledning av forskningsprojekt, medan lektorerna kanskeutför olika sorters institutionsarbeten. När det gäller de studerande så ärkraven på DI-studerande och IB-linjen olika, och dessa skall deklarerasseparat för dessa objekt:

Ex. Människa - namn - personnummer - adress

Personalmedlem Studerande - institution - matrikelnummer - löneklass - STURE-rapport - undervisningsskyldighet

Lektor Professor DI IB- institutionsarbeten - forskningsprojekt - krav - krav på på 180 sv 160 sv

Om vi nu skapar en instans av objektet (klassen) DI, så ska dennablivande DI ha följande egenskaper:

- namn (ärvs från Människa) - personnummer (ärvs från Människa)

- adress (ärvs från Människa) - matrikelnummer (ärvs från Studerande) - STURE-rapport (ärvs från Studerande) - krav på 180 sv (ärvs från DI)

Java II med Annamari, närpass 3: Objektorienterad design 7

Page 8: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

I början är dessa attribut tomma. Efter att vi har skapat instansen i frågakan vi börja fylla i namn etc:

- namn (ärvs från Människa) Axel - personnummer (ärvs från Människa) 300682-275J

- adress (ärvs från Människa) Tavasthem 13 - matrikelnummer (ärvs från Studerande) 28096 - STURE-rapport (ärvs från Studerande) en lång lista - krav på 180 sv (ärvs från DI) en ännu längre lista

För att Axel inte behöver studera ensam kan vi skapa en ny instans avsamma klass, Stina:

- namn (ärvs från Människa) Stina - personnummer (ärvs från Människa) 010581-253Y

- adress (ärvs från Människa) Tavasthem 15 - matrikelnummer (ärvs från Studerande) 28097 - STURE-rapport (ärvs från Studerande) en lång lista - krav på 180 sv (ärvs från DI) en ännu längre lista

I allmänt språkbruk skulle vi kunna kalla både Axel och Stina för objekt,eller instanser av objekt. Vill vi lära oss Javas språkbruk kommer vi attkalla både Axel och Stina för instanser av klassen DI . Klassen DIutvidgar klassen Studerande, som i sin tur utvidgar klassen Människa.Klassen DI är en subklass av klassen Studerande som är en subklass avklassen Människa. Klassen Människa är en superklass av klassenStuderande som är en superklass av klassen DI. Du kan också användatermerna delklass och överklass i stället för subklass rspektivesuperklass.

Så användbar som det ofta skulle vara att låta ett objekt ärva egenskaperfrån två eller flera olika klasser så till åter Java inte detta! Ex. vi kan intedefiniera en klassLärarstudent som skulle ärva från både Personalmedlemoch Studerande.

Java II med Annamari, närpass 3: Objektorienterad design 8

Page 9: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

FLERFORMIGHET (POLYMORPHISM)

(Franzén talar om ungefär samma sak under termerna skuggning ochöverskuggning.)

När det gäller olika subklasser till en bestämd superklass, så är det ofta såatt alla dessa subklasser har en vissgemensam metod, som ändå tar sig liteolika former beroende på vilken delklass det är frågan om. Ex. bådeklassen Lektor och klassen Professor kunde ha en metod årsrapport .Denna metod skulle planera årsrapporten för den ifrågavarandepersonalmedlemmen. Eftersom det dyker upp lite olika sysslor för lektoreroch professorer så är det bäst att de båda delklasserna definierar var för sigvad som ska komma med i årsrapporten. För en lektor skulle årsrapport tamed exempelvis följande punkter:

- Vilka kurser lektorn har undervisat - Hur många studieveckor per år lektorn har producerat - Vilka förtroendeuppgifter lektorn har haft

- Vilka kurser lektorn själv har gått på- Undervisningsmaterial lektorn har producerat

I professorns motsvarande rapport skulle det kunna så ex. följande:

- Vilka forskarkurser professorn har undervisat- Hur många doktorsavhandlingar hon har handlett- Hur många licensiatavhandlingar hon har handlett- Hur många magisters/DI-avhandlingar hon har handlett- Hur mycket extern finansiering hon har skaffat- Hur många artiklar hon har publicerat- Hur många konferenser hon har hållit föredrag på

Uppgiften av metoden skrivaRapport skulle vara densamma: attskriva ut denna årsrapport när den behövs. Därför väljer vi att kalla dennametod för skrivaRappor t, både för klassen Lektor och för klassenProfessor. Strukturen hos dessa rapporter varierar dock beroende påtjänsteklassen. Det är detta som vi kallar för flerformighet.

Java II med Annamari, närpass 3: Objektorienterad design 9

Page 10: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

Man kan också tänka sig att det fanns en metod med namnetskrivaRapport definierad för klassen Personalmedlem. Eftersom detsäkert finns många olika delklasser till denna överklass utöver våralektorer och professorer, så kommer det att finnas bara mycket allmännasaker att skriva ut i denna metod. Vi säger då att metodenskrivaRapport väljer sin form beroende av hurdant objekt det är somskriver ut sin rapport: om instansen som ska skrivaut sin rapport hör direkttill klassen Personalmedlem, så skrivs det ut bara dessa allmänna saker.Om instansen hör till klassen Lektor, skrivs det ut en lektorsrapport. Ominstansen hör till klassen Professor, skrivs det ut en professorsrapport. Idessa två senare fall säger vi att instanserna i klasserna Lektor ochProfessor överskuggar metoden skrivaRapport i klassenPersonalmedlem:

Ex. Människa - namn - personnummer - adress

Personalmedlem Studerande - institution - matrikelnummer - löneklass - STURE-rapport

- undervisningsskyldighet * skrivaRapport (bara namn etc.)

Lektor Professor DI IB- institutionsarbeten - forskningsprojekt - krav - krav

* skrivaRapport * skrivaRapport

Java II med Annamari, närpass 3: Objektorienterad design 10

Page 11: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

Vi kan tänka osstvå lektorer, Ragnar och Annamari, och två professorer,Kaj och Karin. Deras rapporter skulle kunna ha följande utseende:

klass: Lektor

instans: Ragnar

- Vilka kurser lektorn har undervisat: ������������ �-DYD�,���� �-DYD�,,��ODEE�,

- Hur många studieveckor per år lektorn har producerat: �������������"- Vilka förtroendeuppgifter lektorn har haft:

���������2OLND�LQVWLWXWLRQVDUEHWHQ��IRUVNQLQJVSURMHNW�- Vilka kurser lektorn själv har gått på:

�$YDQFHUDG�$,��VFKDFN�I|U�H[SHUWHU��JLVVDU�����- Undervisningsmaterial lektorn har producerat: 8WPDQDGH�-DYD�SURJUDP�I|U�OLWH�OlQJUH�KXQQD����������6XSHUXWPDQDQGH��-DYD�SURJUDP�I|U�JHQLHU

instans: Annamari

- Vilka kurser lektorn har undervisat: ,QWUR�WLOO�,%��LQWUR�WLOO�,%�.7)��'67�.7)��-DYD���������(;)257��SURVHPL�RP�3ODWRQ��GDWDHWLN

- Hur många studieveckor per år lektorn har producerat����������"

- Vilka förtroendeuppgifter lektorn har haft:�������VLWWHU�Sn�LQVWLWXWLRQVUnGHW- Vilka kurser lektorn själv har gått på LPPDWHULDDOLRLNHXGHW�YHUNRVVD��KLVWRULHILORVRIL- Undervisningsmaterial lektorn har producerat: (QNOD�-DYD�SURJUDP�I|U�Q\E|UMDUH

Java II med Annamari, närpass 3: Objektorienterad design 11

Page 12: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

Våra två professorer, däremot, kunde ha följande rapporter:

klass: Professorerinstans: Kaj

- Vilka forskarkurser professorn har undervisat �����������$GYDQFHG�YHULILFDWLRQ�DOJRULWKPV��������������������������������������0XOWLPHGLD�

- Hur många doktorsavhandlingar han har handlett �

- Hur många licensiatavhandlingar han har handlett ��

- Hur många magisters/DI-avhandlingar han har handlett �����

- Hur mycket extern finansiering hon har skaffat ��������� É

- Hur många artiklar han har publicerat ���

- Hur många konferenser han har hållit föredrag på�

instans: Karin

- Vilka forskarkurser professorn har undervisat �����������(YHQ�PRUH�DGYDQFHG�YHULILFDWLRQ�DOJRULWKPV��������������������������������������(PEHGGHG�V\VWHPV�

- Hur många doktorsavhandlingar hon har handlett �

- Hur många licensiatavhandlingar hon har handlett ��

- Hur många magisters/DI-avhandlingar hon har handlett ���

- Hur mycket extern finansiering hon har skaffat �������� É

- Hur många artiklar hon har publicerat ��

- Hur många konferenser hon har hållit föredrag på ��

Java II med Annamari, närpass 3: Objektorienterad design 12

Page 13: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

Som vi ser av exemplen ovan, rapportens struktur, dessutformning, berorpå vilken klass instansen som skriver ut sin rapport till hör: Ragnar ochAnnamari skriver ut lektorsrapporter medan Kaj och Karin skriver utprofessorsrapporter. Rapporternas innehåll varierar naturligtvis beroendepå vilken instans det är som skriver ut sin rapport: även om Ragnar ochAnnamari får liknande tomma blanketter att fylla i, kommer de att skrivaolika saker i sina rapporter, för de har hållit och gått på olika kurser.

Det som ärvs är strukturen, inte innehållet. Varje instans av enklassärver variablerna och metoderna av sin klassom vi inte anger annat.Det som varierar med flerformighet är strukturen (det anses vara självklartatt innehållet varierar). Vi kan ha flera olika metoder med namnetskrivRapport, men de skriver ut olika saker beroende på vilken sortsinstans som anropar dem.

SLUT PÅ TEORIN, DAGS FÖR JAVA -EXEMPEL!!!

Java II med Annamari, närpass 3: Objektorienterad design 13

Page 14: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

Manniska.java

import java.io.*;import javagently.*;

class Manniska {

// instansvariabler - varje instans av ett objekt har // dessa

String namn;

// konstruktor - dessa sker när vi skapar nya instanser// av denna klass

Manniska() { namn = ""; antal++; // en ny människa till har skapats

}

// instansmetoder - detta kan de enskilda instanserna // utföra

void presentera() throws IOException {

BufferedReader in = Text.open(System.in);

System.out.println("Hej, jag heter " + namn + "! ");

}

// klassvariabler - gäller bara för klassen som helhet

static int antal;

}

Java II med Annamari, närpass 3: Objektorienterad design 14

Page 15: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

Varje instans av klassen Manniska som vi skapar kommer att fåinstansvariablerna och instansmetoderna från denna klass:

Manniska + antal (bara klass) - namn

* presentera

- namn - namn - namn - namn * presentera * presentera * presentera * presentera

För att någonting skulle HÄNDA i vårt programsystem måste vi ha enklass som har en main-metod. Det är denna som utgör programmet somkörs. Här berättar vi bara hur klassen Manniska.java ser ut, och hur dessolika instanser skulle se ut. Vi ser också vad som händer när vi skapar eninstans; det ser vi av klassens konstruktor :

// konstruktor - dessa sker när vi skapar nya instanser// av denna klass

Manniska() { namn = ""; antal++; // en ny människa till har skapats

}

För varje nyn instans av klassen Manniska som vi skapar kommerinstansvar iabeln namn at initialiseras till tomsträng, och klassvar iabelnantal i själva klassen att ökas med 1; på detta sätt kan vi lätt hålla redapå hur många människor vi har skapat.

Varje instans har sina egna instansvariabler. Klassvariablerna förekommerbara på ett ställe - klassen själv - och i ett exemplar.

Java II med Annamari, närpass 3: Objektorienterad design 15

Page 16: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

Larare.java och Elev.java

import java.io.*;import javagently.*;

class Larare extends Manniska {

// instansvariabler - varje instans av ett objekt har // dessa

String titel;

// konstruktor - dessa sker när vi skapar nya instanser// av denna klass

Larare() { titel = ""; }

// instansmetoder - detta kan de enskilda instanserna // utföra

void presentera() throws IOException {

BufferedReader in = Text.open(System.in);

System.out.println("Hej, jag heter " + titel + " " + namn + "! ");

}

void mänskligtPresentera () throws IOException { super.presentera();

}

}

Java II med Annamari, närpass 3: Objektorienterad design 16

Page 17: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

Vi ser att klassen Larare nu bli r en delklass av klassen Manniska; denutvidgar klassen Manniska. Dvs. varje instans av klassen Larare ärver allade attribut som en instans av klassen Manniska skulle ha (namn ochpresentera ). Därutöver kommer varje lärare att ha egna attribut ochmetoder:

- namn (ärvs från Manniska)- titel* presentera (överskuggar metoden presentera från Manniska)* mänskligtPresentera (till handahåller ändå metoden presentera, såsom den ser ut i klassen Manniska - i vissa situationer, ex. på semesterresor, vill också lärare vara vanliga människor ... )

Konstruktorn visar att när en ny lärare skapas, sätts titeln till t omsträng.

Enligt Franzén ärvs konstruktorer inte. Jag är inte säker på vad hanmenar med detta: när vi skapar nya instanser av klassen Larare så är dessasamtidigt nya människor, och de räknas alldeles korrekt in i klassvariabelnantal i klassen Manniska såsom vi strax skall se. Men, låt ossförst taen titt på klassen Elev:

Java II med Annamari, närpass 3: Objektorienterad design 17

Page 18: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

import java.io.*;import javagently.*;

class Elev extends Manniska {

// instansvariabler - varje instans av ett objekt har// dessa

int matr, antalkurser;Kurs [] kurser;

// konstruktorer - dessa sker när vi skapar nya instanser// av denna klass

Elev () { kurser = null; antalkurser = 0; }

Elev(int mnr) { matr = mnr; kurser = null; antalkurser = 0;}

Elev(int mnr, String n) {

matr = mnr; namn = n; // nedärvs från Manniska kurser = null; antalkurser = 0;}

// instansmetoder - detta kan de enskilda instanserna// utföra

void presentera() throws IOException {

BufferedReader in = Text.open(System.in);

System.out.println("Hej, jag heter " + namn + ", matrikelnr " + matr + "! ");

}

Java II med Annamari, närpass 3: Objektorienterad design 18

Page 19: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

void mänskligtPresentera () throws IOException {

super.presentera(); }

void deltar ( Kurs önskadKurs ) {

önskadKurs.antal++; // ökas vid den önskade kursen if (kurser == null) kurser = new Kurs [50]; kurser[antalkurser] = önskadKurs; antalkurser++; // för eleven i fråga

}

}

Vi ser att varje elev har följande egenskaper:

- namn (ärvs från Människa)- matr- antalkurser- kurser (en lista över elevens kurser)* presentera (överskuggar metoden i Manniska)* mänskligtPresentera (till handahåller ändå metoden från Människa)* deltar (i olika kurser)

Dessutom har vi hela tre olika konstruktorer för elever:

Elev(), om vi inte vet någonting om eleven i fråga.

Elev(mnr), om vi känner till matrikelnumret till eleven.

Elev(mnr, n), om vi känner till både matrikelnumret och namnet.

Nu kan vi äntligen se på ett program som skapar dylika instanser ochaktiverar dem ... (vi lämnar objektet (klassen) Kurs för lite senare).

Java II med Annamari, närpass 3: Objektorienterad design 19

Page 20: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

Manniskotest.java

import java.io.*;import javagently.*;

class Manniskotest {

/* Klassen Manniskotest exemplifierar nedärvning och polymorfi; klasserna Larare och Elev utvidgar Manniska, och överskuggar dess metod presentera.

*/

public static void main (String [] args) throwsIOException {

Manniska RW = new Manniska();Manniska AMS = new Manniska();

RW.namn = "Ragnar";AMS.namn = "Annamari";

RW.presentera();AMS.presentera();

/* System.out.println("Annamari har " + AMS.antal + " medl."); Kommer att skriva ut samma antal som hela klassen har; syftar alltså till klassvariabeln antal i den klass AMS tillhör

*/

Larare Ralph = new Larare();Larare Paul = new Larare();

Ralph.namn = "Ralph Back";Ralph.titel = "Professor";Paul.namn = "Paul Lindholm";Paul.titel = "Lektor";

System.out.println("\n");

Java II med Annamari, närpass 3: Objektorienterad design 20

Page 21: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

Ralph.presentera();Paul.presentera();

System.out.println("\n");

Elev Ann = new Elev(13012);Elev Bo = new Elev(14516);

/* Konstruktorn in klass Elev kräver att matrikelnummern kommer med. Man kan ju också sätta dit en ny konstruktor utan matrikelnummer.*/

Elev Carin = new Elev();

Ann.namn = "Ann Saarela";Bo.namn = "Bo Persson";Carin.namn = "Carin Sund";

Ann.presentera();Bo.presentera();Carin.presentera();

System.out.println("\n");

System.out.println("människoklassen har " +Manniska.antal + " medl.");

/* testar superklassen - även om Ann tolkas som en Manniska, ändras inte hennes presentation!!!

Manniska AnnHemma = (Manniska) Ann; AnnHemma.presentera();

... producerar matrikelnummer och allt i utskriften.

System.out.println("människoklassen har " + Manniska.antal + " medl.");

... visar att antalet människor inte har ändrats; Ann och AnnHemma syftar till ett och samma objekt.

*/

Java II med Annamari, närpass 3: Objektorienterad design 21

Page 22: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

Ann.mänskligtPresentera();Ralph.mänskligtPresentera(); }}

Låt oss ta en närmare titt på programmet:

Manniska RW = new Manniska();Manniska AMS = new Manniska();

Nya instanser av objekt (klasser) kan vi alltså skapa med kommandot new.Då exekveras konstruktorn för den önskade klassen, och variabelnamnet(här RW och AMS) börjar peka på (referera) till den nya instansen. Det ärmed hjälp av denna referens som vi därefter kan nå den nya instansen.Principen är helt samma som hos arrays och arraynamn - det är ju där somdu redan har stött på kommandot new.

Java hittar själv den önskade klassen, bara den finns under samma områdesom programmet Manniskotest.java. Vi behöver inte exportera klasseneller dylikt.

RW.namn = "Ragnar";AMS.namn = "Annamari";

Här får våra nya instanser namn - konstruktorn för klassen Manniska har julämnat dom tomma.

RW.presentera();AMS.presentera();

Här anropar våra nya instanser sin metod presentera.

Observera, att fast jag bara skapat två instanser direkt ur klassen Manniska,så räknas också alla våra elever och lärare som människor, eftersom det ikonstruktorn för människoklassen står följande:

Manniska() { namn = ""; antal++; // en ny människa till har skapats}

Java II med Annamari, närpass 3: Objektorienterad design 22

Page 23: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

Således, trots vad Franzén säger, gäller konstruktorn i superklassenockså i delklasserna. Varje lärare och varje elev är en människa, ochräknas till antalet människor.

I programmet ovan har vi alltså följande objekt (eller instanser av objekt):

var iabelnamn: klass:

AMS ManniskaRW ManniskaRalph Larare Paul Larare Ann ElevBo ElevCarin Elev

Variabelnamnen ovan är pekare, likadana referenser som vi har för arrays.Situationen i programmet ser alltså följande ut:

AMS

RW

Ralph

Paul

Ann

Bo

Carin

Om du börjar skriva kommandon typ Ann = Bo, då börjar båda pekarnapeka på Bo, och vi tappar bort stackars Ann.

Java II med Annamari, närpass 3: Objektorienterad design 23

Page 24: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

Kurs.java

import java.io.*;import javagently.*;

class Kurs {

// instansvariabler - varje instans av ett objekt har// dessa

int kurskod, antal;String kursnamn;Larare examinator;Elev [] deltagare;

// konstruktorer - dessa sker när vi skapar nya instanser// av denna klass

Kurs () { antal = 0; deltagare = null; }

Kurs(int kod, String namn) { kurskod = kod; kursnamn = namn; antal = 0; deltagare = null; examinator = null; }

}

Här definierar vi ett objekt (en klass) kurs. Varje kurs har följandeegenskaper:

Kurs- kurskod (int)- antal (int)- kursnamn (String)- examinator (Larare)- Deltagare (Elev [], dvs. en array av Elever)

Java II med Annamari, närpass 3: Objektorienterad design 24

Page 25: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

En Kurs har två konstruktorer: en tom, och en som vi kan använda oss avifall vi känner till kurskoden och kursnamnet.

Låt oss se hur vi kan skapa kurser i ett (rätt så komplicerat) program:

Kurssystem.java

import java.io.*;import javagently.*;

class Kurssystem {

/* Klassen Kurssystem exemplifierar nedärvning och polymorfi; klasserna Larare och Elev utvidgar Manniska. Elementär pekar- hantering kommer med.

*/

public static void main (String [] args) throws IOException {

BufferedReader in = Text.open(System.in);

int antal, num, svar;String namn;Elev [] årskurs;

Larare RW = new Larare();Larare AMS = new Larare();

RW.namn = "Ragnar Wikman";RW.titel = "lektor";AMS.namn = "Annamari Soini";AMS.titel = "timlärare";

System.out.println("\n");

RW.presentera();AMS.presentera();

System.out.println("\n");

Kurs Intro = new Kurs(6551, "Introduktion till Informationsbehandling");Kurs Java = new Kurs(6567, "Grundkurs i Programmering/Java");

Intro.examinator = RW;Java.examinator = AMS;

Text.prompt("Hur många elever i denna årskurs? "); antal = Text.readInt(in); årskurs = new Elev [antal];

Intro.deltagare = new Elev [antal];Java.deltagare = new Elev [antal];

for (int i = 0; i < antal; i++) {

Text.prompt("Ge matrikelnummer: "); num = Text.readInt(in); Text.prompt("Ge namn: "); namn = in.readLine(); årskurs[i] = new Elev(num, namn); }

Java II med Annamari, närpass 3: Objektorienterad design 25

Page 26: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

// Registreringen börjar:

for (int i = 0; i < antal; i++) {

Text.prompt(årskurs[i].namn + ", deltar du i intro? 0 (nej) eller 1 (ja): "); svar = Text.readInt(in); if (svar == 1) { årskurs[i].deltar(Intro); // antal deltagare på kursen ökas med 1 Intro.deltagare[Intro.antal - 1] = årskurs[i]; // arrayn börjar från 0 } Text.prompt(årskurs[i].namn + ", deltar du i java? 0 (nej) eller 1 (ja): "); svar = Text.readInt(in); if (svar == 1) { årskurs[i].deltar(Java); Java.deltagare[Java.antal - 1] = årskurs[i]; }

}

// Dags att kolla läget:

System.out.println("\n\nÅrskursen");System.out.println("======================================================\n");for (int i = 0; i < antal; i++) {

System.out.println(årskurs[i].namn + " " + årskurs[i].matr + " tar: " ); for (int j = 0; j < årskurs[i].antalkurser; j++) System.out.println(årskurs[i].kurser[j].kursnamn); System.out.println(); }

System.out.println("\n\n" + Intro.kursnamn + " " + Intro.kurskod + " av " + Intro.examinator.titel + " " + Intro.examinator.namn );System.out.println("======================================================\n");

for (int i = 0; i < Intro.antal ; i++) {

System.out.println( Intro.deltagare[i].namn + " " + Intro.deltagare[i].matr ); }

System.out.println("\n\n" + Java.kursnamn + " " + Java.kurskod + " av " + Java.examinator.titel + " " + Java.examinator.namn );System.out.println("======================================================\n");

for (int i = 0; i < Java.antal ; i++) {

System.out.println( Java.deltagare[i].namn + " " + Java.deltagare[i].matr );

}

}

}

Java II med Annamari, närpass 3: Objektorienterad design 26

Page 27: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

Låt oss rita en skiss över systemet:

årskurs : en array som består av (referenser till ) Elever

... ...

Varje elev registrerar sitt eget namn och matrikelnummer hos sig själva. Arrayn har bara en referens till elevinstansen.

Varje elev som hör till årskursen registreras här. När våra elever nuregistrerar sig på de olika kurserna, kopieras denna referens till eleven ifråga till kursens deltagarlista:

...

Intro.deltagare

Vi hade två instanser av Kurs i vårt exempelprogram:

Kurs- kurskod (int) : 6551- antal (int) : ex. 72- kursnamn (String) : Introduktion till Informationsbehandling- examinator (Larare) : RW (referens till Ragnar-objektet)- Deltagare (Elev [], dvs. en array av Elever) arrayn ovan

Kurs- kurskod (int) : 6576- antal (int) : ex. 64- kursnamn (String) : Grundkurs i Programmering/Java- examinator (Larare) : AMS (referens till Annamari-objektet)- Deltagare (Elev [], dvs. en array av Elever): en likadan array som ovan

Java II med Annamari, närpass 3: Objektorienterad design 27

Page 28: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

Det som nu gör systemet så fint är att informationen om varje elev lagrasbara på ett ställe, hos elev-instansen. Där hittar vi namnet, matrikelnumretoch antalet samt listan över kurser eleven anmält sig till .

På motsvarande sätt lagras informationen över examinatorerna där vi harskapat lärarinstanserna. Där hittar vi namnet och titeln.

Det som lagras i de tre tabellerna - årskursen, introkursen och javakursen -är referenser till eleverna. Dessa referenser är adresser till de ifrågavarandeelevinstanserna. Genom att följa adresserna hittar vi eleven, hans/hennesnamn och matrikelnummer etc.

Ok ... det var INTE lätt. Men det går att förstå om ni tar och ritar hela storahärligheten på papper, och håller noga reda på vilka instanser som hör tillvilka klasser, och vilka attribut de har.

Vi ska se på ett annat exempel, någonting som dagspressen så gott somdagligen påminner oss om ...

Suomitytto.java Suomityttokisa.javaSuomityttoAD.java Antidoping.java

Låt oss se vad vi har i klassen Suomityttö (observera, att det är bäst attlämna bort skanderna ur klassnamnen; operativsystemet som lagrar våraklasser som filer kan få magont av de skandinaviska bokstäverna ...). Vilagrar de attribut som intresserar oss mest ...

- gold * wonGold + FinGold (klassvariabel) - silver * wonSilver + FinSilver (klassvariabel) - bronze * wonBronze + FinBronze (klassvariabel) - totals + FinTotals (klassvariabel)

Java II med Annamari, närpass 3: Objektorienterad design 28

Page 29: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

class Suomitytto {

// instansvariabler - varje instans av ett objekt har// dessa

int gold;int silver;int bronze;int totals;

// konstruktor - dessa sker när vi skapar nya instanser// av denna klass

Suomitytto() { gold = 0; silver = 0; bronze = 0; totals = 0;}

// instansmetoder - detta kan de enskilda instanserna // utföra

void wonGold() { gold++; FinGold++; totals++; FinTotals++;}

void wonSilver() { silver++; FinSilver++; totals++; FinTotals++;}

void wonBronze() { bronze++; FinBronze++; totals++; FinTotals++;}

// klassvariabler - dessa finns bara på ett enda ställe, i klassen själv

static int FinGold;static int FinSilver;static int FinBronze;static int FinTotals; }

Java II med Annamari, närpass 3: Objektorienterad design 29

Page 30: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

Varje "Suomityttö" har alltså sitt eget medaljsaldo att hålla reda på.Därutöver håller själva klassen Suomitytto reda på vårt sammanlagdamedaljsaldo.

Låt oss se på Suomityttökisa (medan allt ännu var frid och fröjd ...):

import java.io.*;import javagently.*;

class Suomityttokisa {

public static void main (String [] args) {

Suomitytto Pirjo = new Suomitytto(); // ManninenSuomitytto Virpi = new Suomitytto(); // KuitunenSuomitytto Kati = new Suomitytto(); // SundqvistSuomitytto Kaisa = new Suomitytto(); // VarisSuomitytto Milla = new Suomitytto(); // Jauho

Pirjo.wonGold();Virpi.wonGold();Kati.wonSilver();Kaisa.wonBronze();Milla.wonSilver();Kaisa.wonSilver();Pirjo.wonSilver();Virpi.wonSilver();

System.out.println("Pirjo har " + Pirjo.gold + " guld");System.out.println("Pirjo har " + Pirjo.silver + " silver");System.out.println("Pirjo har " + Pirjo.bronze + " brons");System.out.println("Pirjo har " + Pirjo.totals + " medaljer totalt\n\n");

System.out.println("Virpi har " + Virpi.gold + " guld");System.out.println("Virpi har " + Virpi.silver + " silver");System.out.println("Virpi har " + Virpi.bronze + " brons");System.out.println("Virpi har " + Virpi.totals + " medaljer totalt\n\n");

System.out.println("Kati har " + Kati.gold + " guld");System.out.println("Kati har " + Kati.silver + " silver");System.out.println("Kati har " + Kati.bronze + " brons");System.out.println("Kati har " + Kati.totals + " medaljer totalt\n\n");

System.out.println("Kaisa har " + Kaisa.gold + " guld");System.out.println("Kaisa har " + Kaisa.silver + " silver");System.out.println("Kaisa har " + Kaisa.bronze + " brons");System.out.println("Kaisa har " + Kaisa.totals + " medaljer totalt\n\n");

System.out.println("Milla har " + Milla.gold + " guld");System.out.println("Milla har " + Milla.silver + " silver");System.out.println("Milla har " + Milla.bronze + " brons");System.out.println("Milla har " + Milla.totals + " medaljer totalt\n\n");

System.out.println("Finland har " + Suomitytto.FinGold + " guld");System.out.println("Finland har " + Suomitytto.FinSilver + " silver");System.out.println("Finland har " + Suomitytto.FinBronze + " brons");System.out.println("Finland har " + Suomitytto.FinTotals + " medaljer totalt");

} }

Java II med Annamari, närpass 3: Objektorienterad design 30

Page 31: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

Men ... alla minns vi väl hur det gick sen ... Låt ossse på vårt följandeprogram, SuomityttoAD.java (AD som AntiDoping):

class SuomityttoAD {

// instansvariabler - varje instans av ett objekt har dessa

String name;int gold;int silver;int bronze;int totals;boolean dope;

// konstruktor - dessa sker när vi skapar nya instanser av denna klass

SuomityttoAD() { name = ""; gold = 0; silver = 0; bronze = 0; totals = 0; dope = false;}

// instansmetoder - detta kan de enskilda instanserna utföra

void wonGold() { gold++; FinGold++; totals++; FinTotals++;}

void wonSilver() { silver++; FinSilver++; totals++; FinTotals++;}

void wonBronze() { bronze++; FinBronze++; totals++; FinTotals++;}void blevFast() {

FinGold = FinGold - gold; // de allmänna konsekvenserna FinSilver = FinSilver - silver; FinBronze = FinBronze - bronze; FinTotals = FinTotals - (gold + silver + bronze); gold = 0; // de personliga konsekvenserna silver = 0; bronze = 0; totals = 0; dope = true; name = name + "-polo"; }

Java II med Annamari, närpass 3: Objektorienterad design 31

Page 32: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

// klassvariabler - dessa finns bara på ett enda ställe, i klassen själv

static int FinGold;static int FinSilver;static int FinBronze;static int FinTotals;

}

Koden torde tala för sig själv: konsekvenserna för doping är sorgliga, bådeför medaljören själv och hela landslaget. Hennes personliga medaljsaldosätts till 0, och hennes medaljer tas bort ur det allmänna finländskamedaljsaldot.

(Observera, att koden ovan gäller bara för de individuella prestationerna;om nån av laget har dopat sig, och åker fast, mister alla deltagarna sinamedaljer i lagtävlingarna. Detta var dock så sorgligt att jag inte hade hjärtaatt koda det.)

För att lära våra tävlare vett och etikett, låt oss se på följande program,Antidoping.java (utöver farorna med doping ska programmet lära dig attlagra våra tävlare i en array; definitionen på Suomitytto har också ändratsen aning, här användar vi klassen SuomityttoAD med dessblevFast-metod...):

import java.io.*;import javagently.*;

class Antidoping {

static SuomityttoAD deltagartab [];

public static void main (String [] args) throws IOException {

BufferedReader in = Text.open(System.in);

deltagartab = new SuomityttoAD[5] ;

int guld, silver, brons;String dopare;

Java II med Annamari, närpass 3: Objektorienterad design 32

Page 33: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

for (int i = 0; i < 5; i++) {

deltagartab[i] = new SuomityttoAD(); Text.prompt("Ge namnet på flickan: "); deltagartab[i].name = Text.readString(in); Text.prompt("Hur många guld: "); guld = Text.readInt(in); // använder klassvariabeln guld, // inte instansens egen - // den påverkas av nästa kommando: for (int j = 1; j <= guld; j++) { deltagartab[i].wonGold(); } Text.prompt("Hur många silver: "); silver = Text.readInt(in); for (int j = 1; j <= silver; j++) { deltagartab[i].wonSilver(); }

Text.prompt("Hur många brons: "); brons = Text.readInt(in); for (int j = 1; j <= brons; j++) { deltagartab[i].wonBronze(); }

} // for-loopen för varje SuomityttoAD

System.out.println("\n\n\n");

// Genomgång av flickorna ... en flicka i sänder:

for (int i = 0; i < 5; i++) {

System.out.println(deltagartab[i].name + " har " + deltagartab[i].gold + " guld");System.out.println(deltagartab[i].name + " har " + deltagartab[i].silver + " silver");System.out.println(deltagartab[i].name + " har " + deltagartab[i].bronze + " brons");System.out.println(deltagartab[i].name + " har " + deltagartab[i].totals + " medaljer totalt\n\n");

} // och genomgång av hela gänget ...

System.out.println("Finland har " + SuomityttoAD.FinGold + "guld");System.out.println("Finland har " + SuomityttoAD.FinSilver + "silver");System.out.println("Finland har " + SuomityttoAD.FinBronze + "brons");System.out.println("Finland har " + SuomityttoAD.FinTotals + " medaljer totalt");

Java II med Annamari, närpass 3: Objektorienterad design 33

Page 34: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

System.out.println("\n\n Och så börjar ANTIDOPING! Resultatenströmmar in!! ");System.out.println("Avsluta med SLUT i stället för namn!");

dopare = "ingen";

while (!(dopare.equals("SLUT"))) { for (int j = 0; j < 5; j++) if (deltagartab[j].name.equals(dopare)) deltagartab[j].blevFast(); Text.prompt("(Nästa) dopare, avsluta med SLUT: "); dopare = Text.readString(in); }

System.out.println("\n\n\n");

System.out.println("KESTÄR INTE! Det som finns kvar är: \n\n");

for (int i = 0; i < 5; i++) {

System.out.println(deltagartab[i].name + " har " + deltagartab[i].gold + " guld");System.out.println(deltagartab[i].name + " har " + deltagartab[i].silver + " silver");System.out.println(deltagartab[i].name + " har " + deltagartab[i].bronze + " brons");System.out.println(deltagartab[i].name + " har " + deltagartab[i].totals + " medaljer totalt\n\n");

}

System.out.println("Finland har " + SuomityttoAD.FinGold + " guld");System.out.println("Finland har " + SuomityttoAD.FinSilver + " silver");System.out.println("Finland har " + SuomityttoAD.FinBronze + " brons");System.out.println("Finland har " + SuomityttoAD.FinTotals + " medaljer totalt");

System.out.println("\n\nFY SKÄMS! Tävlingsförbud: ");

for (int i = 0; i < 5; i++) if (deltagartab[i].dope)System.out.println(deltagartab[i].name);

} // main

} // class

Java II med Annamari, närpass 3: Objektorienterad design 34

Page 35: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

Vårt sista program, Kompistest.java med klassen Kompis.java

ska föra osstill gladare stämningar. Alla tycker vi ju om att ha kompisar,och ett av de lättaste sätten att få nya dito är att bli presenterad av sinkompis åt andra . Följande program ska göra detta. Förutom vett ochetikett lär det dig också en ny datastruktur , en länkad lista.

Idén med kompislistan är följande:

Varje person i listan "pekar på" sin kompis, till s vi kommer till den sistapersonen, som inte vill presentera någonny kompis. Dylika "ingen"-pekarekallar vi för null -pekare eller null -referenser i Java - du har redan setttermen i några array-program. Allmänt vill en null -referens säga att vi haren referensvariabel, men att vi inte ännu har skapat det objekt som dennareferens kommer att peka på. Så fort vi skapar en sådan i en new-sats, ellerlåter vår referens peka på en redan skapad objekt av rätt datatyp slutar denatt vara en null -referens.

När en referens/pekare INTE pekar på något objekt, är det ytterstviktigt att se till att vi sätter värdet null där! Annars försöker systemet tolkadess innehåll - antagligen minnesskräp - som en verklig adress till objektet. Så här ser en Kompis ut:

- namn - kaveri

* presentera * presenteraKompis

+ antal (klassvariabel)

Java II med Annamari, närpass 3: Objektorienterad design 35

Page 36: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

import java.io.*;import javagently.*;

class Kompis {

// instansvariabler - varje instans av ett objekt har dessa

String namn;Kompis kaveri;

// konstruktor - dessa sker när vi skapar nya instanser av denna klass

Kompis(String n) { namn = n; kaveri = null; antal++;

}

// instansmetoder - detta kan de enskilda instanserna utföra

void presentera() throws IOException {

BufferedReader in = Text.open(System.in);

System.out.println("Hej, jag heter " + namn + "!");

}

void presenteraKompis() throws IOException {

BufferedReader in = Text.open(System.in);

System.out.print("Hej, jag heter " + namn);

if (kaveri != null) System.out.println(" och min kompis" + " heter " + kaveri.namn);

}

// klassvariabler - gäller bara för klassen som helhet

static int antal;

}

Konstruktorn förutsätter att vi känner till namnet när vi vill skapa enkompis:

Bo Mats Jan Kim Johan N Johan H Rasmus Pirkka

Java II med Annamari, närpass 3: Objektorienterad design 36

Page 37: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

import java.io.*;import javagently.*;

class Kompistest {

/* Klassen Kompistest exemplifierar en länkad lista.*/

static Kompis du, start;static String namn;

public static void main (String [] args) throws IOException {

BufferedReader in = Text.open(System.in);

Text.prompt("Vad heter du? "); namn = Text.readString(in);du = new Kompis(namn);start = du;

// Om man genast matar in 'ingen' skapas det en kompis med detta namn ...// Därefter får dock kamraden Ingen nöja sig med inga kompisar.

while (! (namn.equals("ingen"))) {

Text.prompt("Hej, " + namn + ", ge namnet på nästa kompis/'ingen': ");

namn = Text.readString(in); if (! (namn.equals("ingen"))) du.kaveri = new Kompis(namn); du = du.kaveri;}

/* alltså:

� �

du �

start du.kaveri

sedan ...

start du

Dvs. start får peka på första personen i li stan, medan du flyttar sig vidare ochpekar allti d på den senaste personen i li stan. Medan både start och du ännupekarpå den första personen, kan vi nå hans kaveri med start.kaveri ellerdu.kaveri . Start lämnar vi vid den första personen, så att vi inte tappar bort vårkompislista. Du däremot flyttar sig vidare i li stan. Varje person kommer turvis attkunna accesseras med du , så länge just han är den aktuella personen.

Java II med Annamari, närpass 3: Objektorienterad design 37

Page 38: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

* / slut på denna kommentar ...

// Genomgång av kompisarna:

du = start; // du får fungera som vår hjälppekare och // gå genom personerna ett i sänder. För att

// kunna accessera en person, måste vi ha en // pekare (referens) till personen. du är

// just en sådan pekare.

while (du != null) {

du.presentera(); du = du.kaveri;

}

System.out.println("\n\noch ännu en gång! Vi är sammanlagt " +

Kompis.antal + " kompisar!");

du = start;

while (du != null) {

du.presenteraKompis(); du = du.kaveri;

}System.out.println();

}

}

Observera, att metoden presenteraKompis avsiktligen är definieradså att ifall man inte har någonkompis - och den sista personen i listan skainte komma med en ny kompis - så presenterar man bara sig själv.

Vad tror du att skulle hända om vi tyckte synd om den sistakompisen och skrev där du.kaveri = start ?

Java II med Annamari, närpass 3: Objektorienterad design 38

Page 39: Det som skiljer objektorienterad programmering, OOP, från den traditionella, imperativa programmeringsstilen, är världssynen. Inom den imperativa traditionen -och hittills har vi

Just så:

Bo Mats Jan Kim Johan N Johan H Rasmus Pirkka

Våra pojkar får springa i en evig karusell , och det önskar vi ju inte

start

Java II med Annamari, närpass 3: Objektorienterad design 39