725G61 - Laboration 5 Grundläggande objektorientering. Johan Falkenjack

Relevanta dokument
Föreläsning 2 Objektorienterad programmering DD1332. Typomvandling

725G61 - Laboration 3 Metoder och abstrakta datatyper. Johan Falkenjack

Dagens program. Programmeringsteknik och Matlab. Objektorienterad programmering. Vad är vitsen med att ha både metoder och data i objekten?

Administrativt. Programmeringsteknik för I1. Dagens program. Objektorienterad programmering

I STONE. I Variabler, datatyper, typkonvertering. I Logiska och matematiska uttryck. I Metoder-returvärde och parametrar. I Villkorssatser if/else

Föreläsning 8 Programmeringsteknik och Matlab 2D1312/2D1305. Klass Object, instans av klass public/private Klassvariabler och klassmetoder

Föreläsning 8 - del 2: Objektorienterad programmering - avancerat

725G61 - Laboration 2 Loopar och arrayer. Johan Falkenjack

725G61 - Laboration 6 Objektorientering, modellering och arv. Johan Falkenjack

Programmering för språkteknologer II, HT2011. Rum

Uppgiften är att beskriva en kvadrat i ett Java program. En första version av programmet skulle kunna se ut så här:

Tentamen. Datalogi I, grundkurs med Java 10p, 2D4112, Lördagen den 30 november 2002 kl , salar E33, E34

Kort om klasser och objekt En introduktion till GUI-programmering i Java

JAVA Mer om klasser och objektorientering

Objektorientering. Objekt och metoder. Objektorientering. Viktiga begrepp. Klass. Objekt. Deklarativ programmering

Laboration 1 - Grunderna för OOP i Java

732G Linköpings universitet 732G11. Johan Jernlås. Översikt. Repetition. Felsökning. Datatyper. Referenstyper. Metoder / funktioner

Objektorienterad Programmering DAT043

Enkla variabler kontra referensvariabel

1 Uppgift 1. a) Skapar ett Company-objekt med hjälp av den överlagrade konstruktorn. Du kan själv välja värden på instansvariablerna.

Lösningsförslag övning 2.

Grundläggande programmering med C# 7,5 högskolepoäng

Java, klasser, objekt (Skansholm: Kapitel 2)

Objektorienterad programmering

Föreläsning 8 - del 1: Objektorienterad programmering (forts.) - Exempel

Vad är ett objekt? Tillstånd och beteende. Vad är ett objekt? Exempel

725G61 - Laboration 7 Implementation av ett API. Johan Falkenjack

TENTAMEN OOP

Bankkonto - övning. Övning 2 Skriv en metod, geträntan, som returnerar räntan.

Grundläggande programmering, STS 1, VT Sven Sandberg. Föreläsning 12

Anmälningskod: Lägg uppgifterna i ordning. Skriv uppgiftsnummer (gäller B-delen) och din kod överst i högra hörnet på alla papper

Objektorienterad programmering i Java

Prova på-laboration i Ruby

Anmälningskod: Lägg uppgifterna i ordning. Skriv uppgiftsnummer (gäller B-delen) och din kod överst i högra hörnet på alla papper

TUTORIAL: KLASSER & OBJEKT

Föreläsning 5-6 Innehåll. Exempel på program med objekt. Exempel: kvadratobjekt. Objekt. Skapa och använda objekt Skriva egna klasser

Objekt och klasser - Introduktion

Modeller, Objekt och Klasser

Föreläsning 5-6 Innehåll

Arv: Fordonsexempel. Arv. Arv: fordonsexempel (forts) Arv: Ett exempel. En klassdefinition class A extends B {... }

Anmälningskod: Lägg uppgifterna i ordning. Skriv uppgiftsnummer (gäller B-delen) och din kod överst i högra hörnet på alla papper

Dagens text. Programmeringsteknik. Mer om Scanner-klassen. Dialogrutor (klassen JOptionPane) Bubbelsortering. Omslagsklasser.

Objekt och referenser

public och private Obs: private inte skyddar mot access från andra objekt i samma klass.

Föreläsning 5 (6) Metoder. Metoder Deklarera. Metoder. Parametrar Returvärden Överlagring Konstruktorer Statiska metoder tostring() metoden javadoc

Inledande programmering med C# (1DV402) Tärningarna ska kastas

Inkapsling tumregler. Åtkomstmodifikatorer, instantiering, referenser, identitet och ekvivalens, samt klassvariabler. public och private

KARLSTADS UNIVERSITET 12/8/09 informatik & datavetenskap Johan Öfverberg, Kerstin Andersson Laboration 4, ISG A04 och DVG A08 HT-09

OOP Objekt-orienterad programmering

Outline. Objektorienterad Programmering (TDDC77) Att instansiera en klass. Objekt. Instansiering. Åtkomst. Abstrakt datatyp.

TDDE10 TDDE11, 725G90/1. Objektorienterad programmering i Java, Föreläsning 2 Erik Nilsson, Institutionen för Datavetenskap, LiU

Malmö högskola 2008/2009 CTS

Idag. Javas datatyper, arrayer, referenssemantik. Arv, polymorfi, typregler, typkonvertering. Tänker inte säga nåt om det som är likadant som i C.

Kompilering och exekvering. Föreläsning 1 Objektorienterad programmering DD1332. En kompilerbar och körbar java-kod. Kompilering och exekvering

Del A (obligatorisk för alla)

Dagens text. Programmeringsteknik. Mer om Scanner-klassen. Dialogrutor (klassen JOptionPane) Bubbelsortering. Omslagsklasser.

Objektorientering: Lagring, räckvidd och livstid

Klasser och objekt. Henrik Johansson. August 20, 2008

(Man brukar säga att) Java är... Denna föreläsning. Kompilering av Java. Historik: Java. enkelt. baserat på C/C++ Allmänt om Java

Lab5 för prgmedcl04 Grafik

Fält av referenser. Konstruktorerna används för att skapa Bilar och Trafikljus.

Idag. statiska metoder och variabler. private/public/protected. final, abstrakta klasser, gränssnitt, delegering. wrapper classes

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 3 Jonas Lindgren, Institutionen för Datavetenskap, LiU

Föreläsning 7: Objektorienterad programmering - introduktion

DAT043 - Föreläsning 7

Programmeringsteknik I. Föreläsning 3: Klasser och arrayer

Objektorienterad programmering D2

Objektorienterad programmering Föreläsning 5

Imperativ programmering. Föreläsning 4

Lektion 7. Datateknik A, Java I, 5 poäng

Objektorientering: Lagring och livstid

Laboration 1: Figurer i hierarki

Objekt och klasser - Introduktion. Objekt. SparKonto.java 2. SparKonto.java 1. Konton.java. Ett objekt har: Ett bankkonto

DD1342 Programkonstruktion för F1,

2203$( Föreläsning ii - Mer om Java bla this och konstruktorer. Exempel: lampa

Grundkurs i programmering, 6 hp (725G61) Dugga 2 tillfälle 2

Föreläsning 10. ADT:er och datastrukturer

Klasser i Java kan ha metoder och egenskaper. Metoder beskriver funktioner som klassen kan utföra. Egenskaper beskriver innehållet i klassen.

TDDC77 Objektorienterad Programmering

Laboration A Objektsamlingar

TDDE10 TDDE11, 725G90. Objektorienterad programmering i Java, Föreläsning 2 Erik Nilsson, Institutionen för Datavetenskap, LiU

Introduktion till Datalogi DD1339. Föreläsning 2 22 sept 2014

Objektorienterad Programmering (TDDC77)

EDAA20 Programmering och databaser. Mål komprimerat se kursplanen för detaljer. Checklista. Föreläsning 1-2 Innehåll. Programmering.

Arrayer (fält)

729G06 Föreläsning 1 Objektorienterad programmering

Grundläggande programmering, STS 1, VT Sven Sandberg. Föreläsning 14

Anmälningskod: Lägg uppgifterna i ordning. Skriv uppgiftsnummer (gäller B-delen) och din kod överst i högra hörnet på alla papper

2D1311 Programmeringsteknik för Bio1 och Bio2, vt 2003 Fiktivt prov På flervalsfrågorna är endast ett svar rätt om inget annat anges i frågan! Det rik

732G Linköpings universitet 732G11. Johan Jernlås. Översikt. Repetition. Muddy. Funktioner / metoder. Punktnotation. Evalueringsordning

EnKlass. Instans 3 av EnKlass. Instans 2 av EnKlass

Den som bara har en hammare tror att alla problem är spikar

Föreläsning 3-4 Innehåll

Laboration 3, uppgift En klass för en räknare

TDDC30 Programmering i Java, Datastrukturer och Algoritmer Lektion 2. Länkade listor Stackar Köer MyList Iteratorer Lab 2 Exceptions Paket

Programmering för språkteknologer II, HT2014. Rum

TDDC30 Programmering i Java, Datastrukturer och Algoritmer Lektion 2. Laboration 2 Datastrukturer En liten uppgift Frågor

Kort repetition. Programmeringsteknik för Bio1 och I1. Vad ska vi lära oss idag? Ett exempel

Objektorienterad programmering i Java I

Frivillig Java-swing-Graphics-lab Programmeringsteknik MN1 vt02

Transkript:

725G61 - Laboration 5 Grundläggande objektorientering Johan Falkenjack November 26, 2013

1 Inledning I labb 1-3 tittade vi på de grundläggande byggstenarna i programmering. Vi lärde oss om variabler, styrstrukturer (villkorssatser och loopar) och abstraktion i form av metoder. I labb 4 tittade vi lite på interaktion och I/O. I den här labben ska vi gå tillbaka till att titta på byggstenar och börja lära oss objektorientering. Objektorientering är ett paradigm, dvs ett tillvägagångssätt för programmering, som har dominerat programmeringsvärlden sedan mitten av 90-talet. Tidigare hade så kallad imperativ respektive funktionell programmering varit de dominerande paradigmen. Imperativ programmering betraktade program som en serie kommandon till datorn, därav namnet. Programmeringsprocessen var linjär och tänkandet kunde beskrivas som "gör A, sedan gör B, sedan..." och så vidare. Det vi gjort hittils i kursen är att betrakta som imperativ programmering. Funktionell programmering byggde dock på ett annat, mer matematiskt, tankesätt. Istället för att se program som en serie kommandon betraktades de som en samling funktioner (i stil med det vi hittils kallat metoder). Precis som matematiska funktioner kunde dessa sedan kopplas ihop. Det är dock viktigt att inse att rena imperativa eller funktionella programmeringsspråk är förhållandevis ovanliga i verkligheten, oftast blandar man stilar beroende på vad som behövs för tillfället. Objektorienterad programmering betraktar inte program vare sig som en serie kommandon eller som en mängd funktioner utan som en mängd klasser och instanser (även kallade objekt) av sådana klasser. Man kan säga att det är ADT-tänket från labb 3 taget till nästa nivå. Istället för att skapa en datatyp och en serie metoder för att manipulera den separat så skapar man en klass som innehåller både data och de metoder som krävs för att manipulera den datan. 2 Vad är klasser? Den primära byggstenen i objektorienterad programmering i Java är klassen. En klass kan liknas vid en mall eller en beskrivning av en viss typ av objekt. En klass kan t.ex. ha som syfte att representera personer i ett registersystem som hanterar studenter (detta kommer vi göra i labb 6). En klass kan dock ha ett mer abstrakt syfte och representera en datastruktur, som t.ex. String, ArrayList eller HashMap som är klasser vi stött på tidigare. Som ni kanske minns var ju String egentligen bara en array med tecken och lite syntaktiskt socker för att hantera sådana på ett smidigt sätt. En klass kan också representera en resurs som löser ett specifikt problem, som klassen Random som vi använde för att generera slumptal. Alla program vi skapat hittills i kursen har varit klasser. Så kommer det vara även i fortsättningen då Java-program alltid är organiserade som en eller flera klasser. Det som skiljer det vi börjar med nu från det vi gjorde tidigare är att vi kommer använda mer än en klass och vi kommer börja skapa instanser 1

av egna klasser. Klasser kan också beskrivas som en mer formaliserad variant av abstrakta datatyper. Istället för att bara vara en underliggande struktur och ett antal metoder för att hantera den strukturen så är metoderna och strukturerna inbakade gemensamt i klassen. Detta kan låta lite underligt till en början men ni kommer snart förstå hur det hänger ihop. 3 Vad är instanser/objekt? Mer intressant än klasser är dock vad man kan göra med dem när man instansierar dem, dvs skapar ett objekt, eller en instans, som tillhör klassen. Vi har gjort instansieringar tidigare i kursen, t.ex. när vi skapat en ny sträng eller en ArrayList. Som ni minns har vi då använt new-kommandot. ArrayList<Integer> minlista = new ArrayList<Integer>(); När new-kommandot används anropas klassens konstruktor. En konstruktor i en klass fyller samma funktion som en konstruktor i en abstrakt datatyp, dvs skapar ett nytt objekt av klassen/typen. När vi t.ex. kör koden ovan för att skapa en ny ArrayList så anropas den klassens konstruktor, en ny instans av klassen skapas och en referens till den nya instansen lagras sedan i variabeln minlista. Vi kan skapa flera instanser av samma klass på samma sätt som vi kan skapa flera olika heltal i ett program, t.ex. flera olika instanser av ArrayList ovan. Alla objekt i Java lagras i referens-variabler och detta är något man måste tänka på när man gör jämförelser mellan olika objekt. Vi kan alltså inte jämföra innehållet i referens-variablerna direkt, utan måste använda metoder för att jämföra det som variablerna refererar till, men vi återkommer till detta senare (i labb 6). 3.1 Relationen mellan klasser och deras instanser Klasser kan ses som generella begrepp, d.v.s. ett koncept, en typ av sak, med vissa egenskaper. T.ex. kan vi prata om en djurart som en klass, t.ex. Tiger. I normala fall har alla tigrar 4 ben, 2 ögon, 1 svans, 1 nos osv. Detta är alltså egenskaper hos själva klassen - djurarten. Ett par instanser av klassen är t.ex. Shere Kahn från Jungelboken eller Tigger från Nalle Puh. De kan ha ytterligare egenskaper, som är specifika för varje individ, t.ex. antal ränder (ett heltal) eller hatar människor (en boolean). En instans är alltså ett faktiskt existerande exempel på den typ av objekt som klassen beskriver. Vi kan kalla det för en instans av en klass eller ett objekt som tillhör klassen, då menar vi samma sak. I den här labben ska vi konstruera en klass som beskriver hur mängder av heltal fungerar, samt testa denna klass genom att instansiera den och skapa ett antal faktiska mängder. 2

4 En objektorienterad mängd I labb 3 byggde vi upp en abstrakt datatyp för att hantera mängder. I de kommande uppgifterna ska vi lösa samma problem objektorienterat. Tanken med detta är att ni redan ska ha viss förståelse för problemet och hur det kan lösas, ni kommer till och med kunna återanvända delar av er kod, så att vi istället kan fokusera på själva objektorienteringen. 4.1 Att skapa en klass I labb 3 skapade vi en grupp metoder som kunde skapa och hantera mängder av heltal. Mängderna representerades dock som arrayer med heltal. Det innebär att vilken array som helst med heltal kunde skickas som argument till metoderna och skulle då betraktas som en fungerande mängd. Det fanns inte heller något säkert sätt att veta om en given heltalsarray representerade en mängd eller ej. När vi skapar en klass löser vi dessa problem genom att skapa en ny typ, då kan vi t.ex. kontrollera att en instans faktiskt är av rätt typ innan vi betraktar den som en mängd. Jämför med när vi t.ex. vill använda klassen String, då måste vi deklarera en specifik String-variabel, variabeln måste ha rätt typ, och den sträng som sedan refereras av den variabeln kan inte förväxlas med någon annan typ. I Java representeras som sagt varje klass med en fil innehållande en klassdefinition. Klassdefintioner, eller klassdeklarationer, har vi gjort flera gånger i kursen och de ser ut som följer: public class ClassName { Först anger vi alltså om klassen är publik eller privat - men vi kommer inte skapa några privata klasser i den här kursen, så ni kan anta att det alltid ska stå public först i klassdeklarationen. Public innebär att klassen kan användas av andra klasser, även om de ligger i andra paket. Sjävla nyckelordet class talar om att det här är en klassdeklaration, och sedan följer namnet på klassen, t.ex. i exemplet ovan ClassName. Klassens innehåll, dess kropp, omsluts sedan av {, och det är innanför dessa parenteser vi skriver all kod som tillhör klassen. När man skapar en ny klass gör man ofta det i ett specifikt paket. Som vi redan har stött på tidigare är det bra att alltid organisera sina klasser i ett paket, ungefär som man alltid sorterar in sina filer på hårddisken i olika kataloger istället för att låta alla filer ligga i samma katalog. Har man många klasser (som t.ex. i projektet senare i kursen) är det bra att skapa olika paket för klasser som har olika syften, eller hör till olika delar av programmet. Ett paket har ett namn och en path, ungefär som sökvägen till en katalog (om ni tittar i projektkatalogen som Eclipse har skapat kommer ni se att det på hårddisken faktiskt har skapats en katalogstruktur som motsvarar er paketstruktur). Paths kan man använda för att skapa hierarkiska strukturer av paket, och visa hur paketen är relaterade till varandra, men det är viktigt först när man skapar riktigt stora program 3

och inget vi kommer att stöta på i den här kursen. Om vi vill att vår klass ska ligga i ett visst paket innehåller filen utöver klassdeklarationen också en paketdeklaration, innan klassdefinitionen: package packagepath.packagename; public class ClassName { När ni skapar era klasser i den här kursen, se till att alltid lägga dem i ett lämpligt paket. Om det inte anges i uppgiften vad paketet ska heta får ni sjävla välja ett lämpligt namn. Nu ska vi lägga grunden till de två klasser som vi kommer använda i den här labben. UPPGIFT 5.1 Skapa ett nytt paket som heter edu.liu.ida.svp725g61. Hela labben skall utföras i detta paket, alltså ska klasserna nedan skapas i det paketet. Skapa sedan en ny klass som heter MySet och som inte innehåller någonting, dvs enbart en fil med en klassdefinition. Vi skulle kunna kalla klassen för Set men vi vill inte förväxla vår klass med någon av de inbyggda Set-klasserna i Java, så för tydlighetens skull kallar vi klassen MySet. Hämta också hem klassen Test från kurshemsidan och lägg till den i projektet. Klassen test använder MySet och precis som i labb 3 får ni avkommentera testkoden allt eftersom för att testa de metoder ni skapar i de olika uppgifterna. 4.2 Instansvariabler I labb 3 lagrade vi alla data för vår mängd i en enda array. Första elementet i arrayen indikerade hur många element som fanns i mängden och resten av arrayen innehöll de faktiska elementen. När vi nu ska tänka objektorienterat kan vi lösa detta problem på ett prydligare sätt, med hjälp av så kallade instansvariabler. En instansvariabel är en variabel som tillhör ett objekt, en instans, och som lagrar de data objektet behöver hålla reda på, t.ex. antal ränder i Tigerexemplet. En instansvariabel är kopplad direkt till objektet men inte specifikt till dess klass, d.v.s. alla tigrar har ränder (vi beskriver i vår klass att varje instans kommer ha den här egenskapen), men olika tigrar har olika antal ränder (varje instans får sin egen variabel och kan lagra sitt eget individuella värde på den här egenskapen). Detta innebär att olika objekt av samma klass kan ha olika värden i sina instansvariabler. En typisk instansvariabel vi kan ha är en sträng som heter name. Säg att vi har en klass som heter Person som ska lagra information om människor. Då kan vi deklarera en instansvariabel på följande sätt: 4

public class Person { public String name; Som vi ser ligger instansvariabler utanför metoder, till och med utanför mainmetoden. Normalt deklarerar man alla instansvariabler (och klassvariabler) högst upp i klassens kropp, d.v.s. före alla klassens metoder, så att vi kan se vilka variabler klassen har direkt i anslutning till klassdeklarationen. Det står inte static framför variabelnamnet och det är detta som indikerar att det är en instansvariabel och inte en klassvariabel (till skillnad från antal ben som är en egenskap hos tigrar som art och alltså en klassvariabel). Precis som för vilken variabel som helst måste vi ange instansvariabelns typ (i det här fallet String) och ge den ett namn (i det här fallet name). Alla instansvariabler är alltid tillgängliga överallt inne i en klass, och en instansvariabel som är deklarerad som public är dessutom tillgänglig utanför instansen. För att komma åt en instansvariabel "från utsidan" använder man så kallad message passing, det görs med punktnotationen vi stött många gånger redan, t.ex. när vi anropat en metod genom att ange instansen vi vill anropa metoden på och sedan metodens namn, såsom med in.nextint() när vi har en Scanner-referens i variabeln in och vill läsa in ett heltal från tangentbordet. Skillnaden här är att det är en variabel och inte en metod vi kommer att ange med hjälp av punktnotationen. Person aperson = new Person(); aperson.name = "Eva"; System.out.println(aPerson.name); I exemplet ovan skapar vi alltså en ny person-instans som vi kallar för aperson, d.v.s. vi skapar en variabel av typen Person och lagrar en referens till en ny instans av Person-klassen. På nästa rad tilldelar vi instansvariabeln name i aperson värdet "Eva", och på raden efter hämtar vi värdet ur samma instansvariabel och skriver ut det. Notera att vi inte har några parenteser efter name i aperson.name, detta beror på att name inte är en metod utan en variabel, till skillnad från nextint() som nämndes ovan. 5

Övning 5.1 Skapa klassen Person enligt det första exemplet ovan, lägg klassen i samma paket där du lagt klassen Test och MySet. Gå sedan till klassen Test och i main-metoden, skapa en ny instans av Person. Ge sedan objektet ett namn och skriv skriv ut namnet med System.out.println(), enligt exemplet ovan. Vad skulle hända om du nu gick till personklassen och bytte ut public mot private framför variablen namn och försökte köra main-metoden i Test igen? Fundera först och testkör sedan. Blev det som du väntat dig? Kom ihåg att ändra tillbaka name till public när du är färdig eftersom vi använder Person i fler exempel. Övning 5.2 Prova att i main-metoden skapa ytterligare en instans av Person som du kan kalla t.ex. anotherperson. Ge anotherperson ett annat namn än aperson. Skriv sedan ut båda objektens namn för att försäkra dig om att de olika Personobjekten har olika namn. 4.3 Konstruktorn I labb 3 skapade vi en konstruktor-metod som hette makeset(). Även när vi objektorienterar skapar vi konstruktorer. När vi använder oss av kommandot new använder vi oss alltid av en konstruktor. T.ex. kan vi skapa en strängvariabel på följande sätt: String name = new String(); Eller en ny ArrayList för heltalsvärden på följande sätt: ArrayList<Integer> minlista = new ArrayList<Integer>(); När vi skapar en klass i Java skapas automatiskt en så kallad default-konstruktor. Denna syns inte och det enda den gör är att skapa ett tomt objekt av klassen. Vill vi t.ex. skapa ett objekt av vår klass MySet skriver vi: MySet mysetinstance = new MySet(); Övning 5.3 Testa att göra detta i main-metoden i klassen Test. Ser ni att det fungerar trots att vi inte någonstans har skapat en metod som heter MySet()? En default-konstruktor är dock inte särskilt intressant utan ofta vill man själv bestämma vad som ska hända när ett objekt skapas. För att skapa en egen 6

konstruktor skapar man en metod med exakt samma namn som klassnamnet och där man inte deklarerar något returvärde, alltså, inte ens void. Konstruktorn för en klass är oftast publik, eftersom man oftast vill att andra klasser ska kunna använda den och skapa nya objekt av klassen - i den här kursen kommer vi alltid att deklarera alla konstruktorer public. Vill vi t.ex. skapa en konstruktor för Person-klassen som ser till att vi inte kan få Person-objekt utan namn skriver vi på följande sätt: public class Person { public String name; public Person(String aname) { name = aname; I konstruktorn spelar det ingen roll om instansvariablerna man tilldelar är publika eller privata. Eftersom konstrukturn jobbar inom den egna klassen och med den instans som just nu skapas kommer man här åt alla instansvariabler oavsett. Det går, precis som med vanliga metoder, att skapa flera olika konstruktorer (de får ju alla samma namn - klassnamnet), förutsatt att de olika konstruktorerna har olika parameterlistor. Om man skapar egna konstruktorer slutar dock default-konstruktorn att fungera, så om vi lagt till konstruktorn i exemplet ovan kan vi sedan inte längre skriva: Person aperson = new Person(); Utan vi måste alltid skicka med ett namn från början när vi vill skapa en ny person: Person aperson = new Person("Eva"); Konstruktorn har inget returvärde utan returnerar alltid en instans av klassen med de värden på instansvariablerna man tilldelat i konstruktorns kropp. 7

UPPGIFT 5.2 Skapa två privata instansvariabler i klassen MySet. Ett heltal som heter size och en heltalsarray som heter contents. Dessa skall bara deklareras (lägg dem allra först i klassens kropp), men inte tilldelas några värden i samband med deklarationen. Skapa sedan en konstruktor i klassen MySet. Konstruktorn skall inte ta några argument. Konstruktorn skall tilldela variabeln size värdet 0 och tilldela contents en ny heltalsarray med storleken 100. Variabeln size fyller nu samma funktion som första elementet i arrayen gjorde i labb 3 och contents fyller funktionen som resten av arrayen gjorde, d.v.s. kommer att innehålla själva elementen. 4.4 Instansmetoder Precis som att vi kan skapa instansvariabler, d.v.s. variabler som är knutna till en viss instans av en klass, så kan vi skapa instansmetoder, d.v.s. metoder som är knutna till en viss instans. Man skriver metoderna på samma sätt som vi skapat metoder tidigare i labbarna, men utan static framför. En instansmetod har alltid tillgång till alla instansvariabler och till de värden som tilldelats just det objekt på vilket metoden anropas. När man säger att man anropar en metod på ett objekt så innebär det att man använder message passing, på samma sätt som när man vill komma åt en instansvariabel. Ett exempel på sådan message passing var när vi anropade nextint() på ett Scanner-objekt i labb 4. //Create new instance of Scanner java.util.scanner in = new java.util.scanner(system.in); //Read the next integer from standard input int num = in.nextint(); Ett exempel på en instansmetod är en utskriftsmetod till personklassen som låter objektet presentera sig. public void hello() { System.out.println("Hello, my name is " + name + "!"); Metoden hello() skulle sedan kunna anropas på följande sätt: Person myperson = new Person("Eva"); myperson.hello(); Ovanstående kod kommer skriva ut "Hello, my name is Eva!" eftersom metoden anropas på ett Person-objekt som vi givit namnet Eva (vi skapade ju en 8

ny konstruktur ovan som tilldelar name-variabeln textsträngen i konstruktorns argument). Övning 5.4 Skapa en konstruktor för Person-klassen som tar en textsträng som parameter, enligt exemplet tidigare i texten. Skapa sedan instansmetoden hello() enligt exemplet ovan, och testa den genom att i main-metoden i klassen Test skapa en ny instans av personklassen och sedan anropa metoden hello() på den instansen. Nu följer ett antal uppgifter som låter er bygga upp klassen MySet. Metoderna är till stor del samma som för labb3 och koden kommer bli ganska liknande. Det är okej att kopiera kod från er lösning på labb 3, men ni kommer behöva skriva om den så att den blir objektorienterad. Efter varje uppgift, testa er lösning genom att avkommentera lämpliga delar av koden i main-metoden i klassen Test. UPPGIFT 5.3 Skriv en instansmetod getsize() i klassen MySet som returnerar storleken av mängden. Metoden ska inte ta några argument och den skall vara publik. UPPGIFT 5.4 Skriv en instansmetod isempty() i klassen MySet som returnerar ett sanningsvärde som representerar huruvida en mängd är tom eller ej. Metoden ska inte ta några argument och den skall vara publik. UPPGIFT 5.5 Skriv en publik instansmetod contains() i klassen MySet som tar ett heltal som argument. Om heltalet finns i mängden ska metoden returnera sant, annars ska den returnera falskt. UPPGIFT 5.6 Skriv en publik instansmetod addelement() i klassen MySet som tar ett heltal som argument. Om heltalet redan finns i mängden ska false returneras (för att signalera att inget lades till). Om inte talet redan finns i mängden ska storleken på mängden räknas upp, talet läggas till (tänk efter vilket index ni ska använda för att lägga till talet i contents) och true ska returneras. 9

UPPGIFT 5.7 Skapa en instansmetod i klassen MySet som heter prettyprint() och som skriver ut innehållet i mängden på samma sätt som prettyprint() i labb 3 gjorde, t.ex. set{ 1, 2, 3, för en mängd med innehållet 1, 2 och 3. Metoden skall inte ta några argument och skall vara publik. UPPGIFT 5.8 Skapa en ny instansmetod i klassen MySet som heter remove() och som tar ett heltal som argument. Om heltalet inte finns i mängden ska false returneras. Om heltalet finns i mängden så ta bort det och returnera true. Metoden remove() kan anta att alla element i mängden är unika, dvs man behöver bara ta bort första förekomsten av ett heltal eftersom det inte ska finnas några fler. Använd samma algoritm (d.v.s. samma typ av lösning) som i labb 3 för att lösa problemet. 4.5 Nyckelordet this Ibland vill man inne i en metod explicit komma åt objektet man anropar metoden på. Detta kan man göra med nyckelordet this som innehåller en referens till det aktuella objektet. Man kan säga att this är ett objekts referens till sig själv. Att använda this är t.ex. bra om man har parameternamn som är samma som namnet på en instansvariabel. Exempelvis i en konstruktor: public class Person { public String name; public Person(String name) { this.name = name; Här är ju instansvariabeln name och parametern name olika variabler, de råkar bara ha samma namn. Med hjälp av this håller vi reda på vilken som är instansvariabel och vilken som är lokal variabel inne i konstruktorn. Det kan också vara aktuellt att använda this om metoden arbetar med en eller flera andra instanser av klassen, som i intersection() nedan, där metoden tar en MySet-instans som argument. Det går att lösa Uppgift 5.9 utan this, men det blir ofta mer lättläst om man använder this och i uppgiften ska ni göra det för att öva på hur this kan användas. 10

UPPGIFT 5.9 Skapa instansmetoden intersection() i klassen MySet, som tar en annan MySetinstans som argument. Metoden skall returnera snittet mellan den aktuella mängden (this) och mängden som skickats in som argument. Mängden som returneras ska vara en ny mängd och den ska byggas upp genom att använda de metoder vi skapat tidigare i labben. Både mängden som intersection() anropas på och mängden som skickas in som argument skall vara oförändrade efter att metoden har körts. 4.6 Klassvariabler och klassmetoder Hittils i labben har vi bara experimenterat med instansvariabler och instansmetoder. I Java kan man dock också arbeta med klassvariabler och klassmetoder. Detta är variabler och metoder som är kopplade direkt till en klass istället för till dess instanser. För en klassvariabel innebär det att den har samma värde för alla instanser och att vi kan komma åt den oavsett om vi har någon instans eller inte. Detsamma gäller för klassmetoder. Metoden Arrays.sort() som användes i labb 2 är ett exempel på en klassmetod. Vi var ju inte tvugna att skapa en instans av Arrays med hjälp av newkommandot för att använda den utan vi kunde anropa metoden direkt med hjälp av klassen, d.v.s. vi anger klassnamnet före punkten istället för variabelnamnet som refererar till en instans av klassen. Klassvariabler och klassmetoder kallas också ofta för static-variabler och static-metoder. Detta beror på att vi måste deklarera dessa som just static, d.v.s. ange nyckelordet static i variabel- eller metoddeklarationen. Ett av många användningsområden för klassvariabler och klassmetoder är för att hålla reda på hur många gånger en klass har instansierats. Tidigare har vi sett exempel med Person-klassen. Kanske vill vi hålla reda på hur många person-instanser vi har i vårt system, eller till och med spara en lista med alla personer som vi skapat (vi återkommer till detta i labb 6). Såhär kan vi deklarera en klassvariabel för att hålla reda på antalet person-instanser i vår Person-klass och se till att vi från början ger den värdet 0 (eftersom vi ju från början inte har några instanser av klassen): public class Person { public String name; public static int numberofpersons = 0; //The rest of the code for this class... 11

Någonstans i vår klass måste vi sedan även se till att variabeln hålls uppdaterad, d.v.s. att värdet räknas upp varje gång vi skapar en ny person-instans. Ett lämpligt ställe att göra det är i kontruktorn, eftersom vi vet att konstruktorn innehåller den kod som körs varje gång en ny instans skapas. UPPGIFT 5.10 Skapa en privat klassvariabel som innehåller ett heltal och heter noofinstances och som initieras med värdet 0. Modifiera sedan konstruktorn så att noofinstances räknas upp varje gång en ny instans skapas. Skapa sedan klassmetoden instances() som inte tar några argument och som returnerar noofinstances. Vi gör noofinstances privat trots att vi vill kunna hämta värdet från den. Detta beror på att om variabeln vore publik så skulle vi även kunna skriva till den från andra ställen i koden, t.ex. från main-metoden som ligger i en annan klass. Detta är lite som att ha en funktion för att manuellt skruva tillbaka tripmätaren i en bil, dvs man skulle inte kunna lita på värdet om alla kan ändra det. Vi återkommer till varför vissa variabler bör vara private i labb 6. 5 Extrauppgifter Övning 5.5 Modifiera konstruktorn så att contents börjar med storleken 1. Modifiera sedan addelement() så att maxstorleken på contents fördubblas varje gång arrayen blir full. För att göra det måste man skapa en ny heltalsarray och kopiera in alla värden som finns i contents innan man ersätter contents med den nya arrayen. Kom ihåg att man kan använda attributet length på en array för att få veta dess maxstorlek. Med hjälp av den här förändringen kan vi göra så stora mängder vi vill och behöver inte oroa oss över att vi kan ha max 100 element. Vi kommer också ta upp max dubbelt så mycket utrymme i minnet som vi faktiskt använder. 12

Övning 5.6 Iochmed Uppgift 5.5 kunde vi ha hur stora mängder som helst (eller åtminstone tills datorns fysiska minne blev fullt). Men om vi lägger till 1 000 element i en mängd och sedan tar bort 997 av dessa och bara har 3 element kvar så har vi en onödigt stor array liggande i minnet. Modifiera remove så att maxstorleken på contents halveras när antalet element sjunker under en tredjedel av den aktuella storleken. Fundera på varför vi inte vill halvera maxstorleken på contents direkt när vi kommer under hälften? Ledning: Vad händer om vi ligger precis på gränsen mellan två storlekar och lägger till och sedan tar bort element flera gånger på raken? 6 Output från Test Testing Testing constructor, isempty() and getsize(): true 0 Testing add(): 0 1 2 2 Testing isempty() and getsize() again: true false 0 2 Testing contains(): false false true true false Testing prettyprint(): set{ set{ 1, 2, 13

Testing remove(): set{ 34, 71, 39, 66, false set{ 34, 71, 39, 66, true set{ 34, 39, 66, true set{ 34, 39, Testing intersection(): set{ 3, 7, 2, 5, set{ 2, 9, 8, 3, set{ 3, 2, Testing instances(): 6 6 6 14