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

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

Föreläsning 4. Klass. Klassdeklaration. Klasser Och Objekt

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

Övning 3. Datateknik A, Java I, 5 poäng

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

TUTORIAL: KLASSER & OBJEKT

Java, klasser, objekt (Skansholm: Kapitel 2)

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

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

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

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

Föreläsning 5-6 Innehåll

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

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

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

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

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

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

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.

JAVA Mer om klasser och objektorientering

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

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

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

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

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

LÖSNINGSFÖRSLAG Programmeringsteknik För Ing. - Java, 5p

Föreläsning 2 Objektorienterad programmering DD1332. Typomvandling

Lite om felhantering och Exceptions Mer om variabler och parametrar Fält (eng array) och klassen ArrayList.

Objekt och referenser

Föreläsning 8. Arv. Arv (forts) Arv och abstrakta klasser

Objektorienterad programmering Föreläsning 5

JAVAUTVECKLING LEKTION 11

DAT043 - Föreläsning 7

Laboration 1 - Grunderna för OOP i Java

Tentamen OOP

Malmö högskola 2008/2009 CTS

LÖSNINGSFÖRSLAG TENTAMEN

Att prova på en enkel Applet och att lära sig olika sätt att hämta data från tangentbordet. Du får även prova på att skapa din första riktiga klass.

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

(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

Objektorienterad programmering i Java I. Uppgifter: 2 Beräknad tid: 5-8 timmar (OBS! Endast ett labbtillfälle) Att läsa: kapitel 5 6

Objektorienterad programmering i Java

Objekt och klasser - Introduktion

1 Egna klasser. 1.1 En punkt-klass

Kopiering av objekt i Java

LÖSNINGSFÖRSLAG TENTAMEN

UML. Klassdiagr. Abstraktion. Relationer. Överskugg. Överlagr. Aktivitetsdiagram Typomv. Typomv. Klassdiagr. Abstraktion. Relationer.

Design av en klass BankAccount som representerar ett bankkonto

Arv innebär att man skapar en ny klass (subklass) utifrån en redan existerande klass (superklass, basklass).

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

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

Lab5 för prgmedcl04 Grafik

Föreläsning 3-4 Innehåll. Diskutera. Metod. Programexempel med metod

F4 Klasser och Metoder. ID1004 Objektorienterad programmering Fredrik Kilander

Objektorienterad Programmering DAT043

Enkla variabler kontra referensvariabel

Malmö högskola 2007/2008 Teknik och samhälle

Föreläsning 3-4 Innehåll

Dynamisk bindning och polymorfism

Objektorienterad programmering

Variabler som hör till enskilda objekt. Deklareras på översta nivån i klassen och i regel som private.

Objektorienterad programmering D2

2I1049 Föreläsning 5. Objektorientering. Objektorientering. Klasserna ordnas i en hierarki som motsvarar deras inbördes ordning

Objektorienterad programmering i Java I

Introduktion till arv

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 Programkonstruktion. Föreläsning 2 2 nov 2016

Klasser och objekt. Henrik Johansson. August 20, 2008

TENTAMEN OOP

Modeller, Objekt och Klasser

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

Del2 Klasser, medlemmar och arv Ämnesområden denna föreläsning:

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

Programmering med Java. Grunderna. Programspråket Java. Programmering med Java. Källkodsexempel. Java API-exempel In- och utmatning.

Lösningsförslag övning 2.

Det finns en referensbok (Java) hos vakten som du får gå fram och läsa men inte ta tillbaka till bänken.

Objektorienterad programmering i Java I

Ett objekt... Exempel: Om ni tittar er runt i föreläsningssalen ser in många olika fysiska föremål:

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

Classes och Interfaces, Objects och References, Initialization

2D1339 Programkonstruktion för F1, ht 2004

Datatyper. Programmering. Att definiera datatyper i Java. Laddade partiklar. (x,y) (Rx,Ry) hh.se/db2004

Föreläsning 13 Innehåll

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

Laboration 1: Figurer i hierarki

Övningar Dag 2 En första klass

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

Dagens föreläsning. Arrayer och klasser. Medan ni väntar: Gå till m.voto.se/prog11 och svara på några gamla tentamensfrågor! (26 januari 2018 F3 1 )

TUTORIAL: SAMLING & KONSOLL

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

TENTAMEN OOP

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

Vem är vem på kursen. Objektorienterad programvaruutveckling GU (DIT011) Kursbok Cay Horstmann: Big Java 3rd edition.

Subklasser och arv Inledning till grafik (JFrame och JPanel). Något om interface. Objektorienterad programvaruutveckling GU (DIT011) Subklasser

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

TDDC77 Objektorienterad Programmering

5. En metod som anropar sig själv a) får inte förekomma i Java-program b) kallas destruktiv c) kallas iterativ d) kallas rekursiv 6. Vilka värden har

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

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

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

Transkript:

Datateknik A, Syfte: Att få en djupare förståelse hur metoder i Java konstrueras och används. Veta vad en konstruktor är och hur vi använder dem för att skapa objekt. Kunna generera dokumentation med hjälp av javadoc. Att läsa: Kursboken, Kapitel 2 (sida 82 88) Kursboken, Kapitel 3 (sida 95 102) Kursboken, Kapitel 4 (sida 121 137) http://java.sun.com/docs/books/tutorial/java/javaoo/classes.html http://java.sun.com/j2se/javadoc/writingdoccomments/index.html

I denna lektion gör vi en utförlig genomgång av metoder i Java. Vi tittar närmare på hur vi skickar och tar emot data från en metod. Vi förklarar vad överlagring av metoder och statiska metoder innebär. Vi tar även en titt på en lite speciell metod nämligen konstruktorn. Avslutningsvis går vi igenom verktyget javadoc för att automatgenerera dokumentation för våra Javaprogram. Robert Jonsson Sida 1

Redan i Lektion 2 började vi titta på vad metoder i Java är och hur vi kan anropa metoder på ett objekt. Vi börjar denna lektion med en kort repetition. En metod definieras alltid med en eller flera modifierare. Vi börjar med en åtkomstmodifierare som regler åtkomsten till metoden (vilka andra objekt som kan anropa metoden). Normalt vill vi att andra objekt ska kunna anropa metoderna och därför används nästan alltid public som åtkomstmodifierare. En metod kan även sättas till private om vi vill att enbart metoder i samma klass ska kunna nå aktuell metod. Efter åtkomstmodifieraren anger vi metodens returtyp. Returtypen berättar om metoden returnerar ett värde tillbaka till den som anropade metoden och i så fall vilken datatyp det returnerade värdet har (kan även vara objektreferenser som returneras). Alla metoder har ett namn med vilken vi kan anropa metoden med. Vi kan själva välja vilket namn metoderna ska ha och vi låter första ordet i metodnamnet ha en liten bokstav. För resterande ord i metodnamnet låter vi första bokstaven i varje ord ha en STOR bokstav (t.ex. ändranamn()). Det finns två undantag vad gäller det jag nyss skrev. main()-metoden måste alltid heta main och även konstruktorn för en klass måste alltid ha ett bestämt namn (kommer vi till lite senare). När vi anropar en metod kan vi skicka med data som metoden behöver eller ska bearbeta. Detta är metodens parametrar. För varje parameter anger vi dess datatyp och ett namn. En metod behöver inte ha några parametrar. Metodens kropp (innehåll) omsluts av matchande klamrar { }. I klassen Person från lektion 2 hade vi en metod med namnet setnamn() och som tog en parameter med namnet n och som var av typen sträng (String). Robert Jonsson Sida 2

Om vi behöver anropa en metod på ett objekt gör vi det genom punktnotation där vi anger namnet på det objekt, vars metod vi vill anropa, följt av namnet på metoden. Om metoden vi anropar finns i samma klass behöver vi inte använda punktnotation utan det räcker då att enbart skriva metodens namn (samt eventuella parametrar metoden behöver). Robert Jonsson Sida 3

Det som händer när en metod anropas är att exekveringen av programmet överförs till den anropade metodens första kodsats. Som nämnts behöver metoderna som anropas inte återfinnas i samma objekt (klass). Metodanrop kan göras mellan olika objekt men fungerar på samma sätt som exemplet i bilden. För att ge en kort förklaring om vad som händer vid metodanrop har jag utgått från exemplet med klasserna Person och PersonTest ovan. Observera att detta är en förenklad beskrivning men som ger en förståelse över hur det fungerar. 1. Den virtuella Javamaskinen anropar vår main()-metoden i klassen PersonTest varpå applikationen startar. Där börjar vi med att skapa ett nytt Person-objekt (ett objekt av typen Person). Här sker egentligen ett metodanrop som överför exekveringen från PersonTest till Person, men detta visar jag inte (förklaras lite senare i lektionen). 2. När vi nu har vårt Person-objekt p1 kan vi anropa dess publika metoder. När vi anropar setnamn() överförs exekveringen till första reden i denna metod (först kopieras eventuella parametrar metoden behöver. I vårat fall namnet på personen Kalle Karlsson). 3. När metoden är klar (eller när vi stöter på nyckelordet return) överförs exekveringen igen till samma ställe i objektet där metodanropet skedde. En metod returnerar alltid när alla programsatser i metoden har exekverats (d.v.s. när vi kommer till den avslutande högerklammern } för metoden). Vill vi av någon anledning returnera från metoden innan alla kod har exekverats görs detta genom att skriva return. 4. Direkt anropar vi nu metoden print() och exekveringen överförs återigen till klassen Person och första raden i print() metoden. 5. När alla programsatser körts i print() överförs exekveringen till raden som följer anropet i PersonTest. 6. När main()-metoden är slut är även applikationen slut (gäller ej vid applikationer som använder grafiska gränssnitt). Exekveringen överförs till den virtuella maskinen (som ju anropade main()-metoden). Där avslutas applikationen. Robert Jonsson Sida 4

I och med att en instansvariabel i en klass deklareras som private förhindras andra objekt att få en direkt tillgång till variabeln och dess värde. Detta är det normala för instansvariabler vilket håller de gömda från andra. För att komma åt de gömda instansvariablerna brukar man implementera publika metoder med vilka man kan sätta nya värden och hämta aktuellt värde, s.k. set()- och get()-metoder. Set()-metoden används för att tilldela den privata instansvariabeln sitt värde, medan get()-metoden används för att lämna ut (returnera) variabelns värde. För att sätta värden i dessa publika set()-metoder (och i andra metoder) används parametrar för att skicka informationen till metoderna när dessa anropas. Robert Jonsson Sida 5

Tittar vi på klassen Person och dess metod setnamn() är tanken med denna metod att sätta namnet på personen. För att göra detta måste metoden ges (eller få skickat) en sträng som representerar personens namn (en sträng eftersom vi i klassens metoddeklaration angett att typen på parametern ska vara en String). Metoden setnamn() kommer att ta emot värdet i denna sträng och lagra den temporärt i variabeln n. Därefter tilldelas vår instansvariabel namn (som är av samma typ) värdet som lagrats i variabeln n. På så sätt kommer objektet att få det namn som skickades till metoden. Variabeln n kommer att existera så länge som metoden exekverar. När metoden returnerar tappar variabeln n sitt värde och n städas bort från minnet. Instansvariabeln namn kommer däremot att behålla sitt värde. Inom parenteserna (som följer metodens namn i metoddeklarationen) anger man vilka parametrar metoden ska ta. Först anges vilken typ det är frågan om, följt av en identifierare (namn på variabeln). Om metoden behöver mer än en parameter används kommatecknet för att skilja parametrarna åt (exempel på detta kommer senare). Robert Jonsson Sida 6

När vi anropar en metod är det viktigt att vi matchar antalet och typ av parametrar. I vårt exempel PersonTest vore det felaktigt att skicka ett meddelande till setnamn()-metoden som inte var av typen String. I bilden ovan är det endast det första anropet till setnamn som är korrekt och tillåtet. De tre följande anropen är inte tillåtna eftersom antingen parameterns typ eller antal är felaktigt. För att visa på ett exempel på metod som har fler än en parameter har jag skrivit klassen Adderare. Denna innehåller en metod som tar två heltal som parametrar. Dessa heltal adderas och resultatet skrivs ut på skärmen. Observera att en metod med fler än en parameter kan ha olika datatyper på parametrarna. Ta en titt på klassen Adderare.java, kompilera och kör den. Klassen finner du bland exemplen som tillhör lektionen. Robert Jonsson Sida 7

Instansvariabler och metoder har alltid en räckvidd som sträcker sig över hela klassen. D.v.s. att de kan användas (kommas åt) från andra metoder i klassen. Parametrar till en metod har däremot en räckvidd som är begränsad till den metod i vilken den deklarerats. Anledningen till parametrar endast lever i metoden är att parametrar har en relativt kort livslängd. Parametern behöver vi enbart för att t.ex. sätta värdet på en instansvariabel eller att utföra någon bearbetning med. Så snart metoden exekverat klart har vi inget behov av den och parametern slutar att existera. Detta betyder att vi i bilden ovan enbart kan referera till variabeln (parametern) n i setnamn()-metodens inuti själva metoden. Vi kan inte komma åt variabeln n och dess värde från t.ex. metoden getnamn(). Robert Jonsson Sida 8

Jag nämnde tidigare att de värden som skickas som parameter kopieras över till metoden i samband med metodanropet. I Java överförs alla parametrar till metoder via s.k. värdeanrop. Detta innebär att när en variabel skickas som parameter till en metod så överförs endast en kopia av parameterns värde till metoden, och metoden kan inte ändra den ursprungliga variabelns värde. Detta låter säkert invecklat och till en början kan det vara svårt att förstå. För de primitiva datatyperna (int, char, double etc) innebär detta att om vi gör en förändring på kopian (t.ex. ett heltal som skickas till en metod) så sker inte denna förändring på originalvariabeln. Eftersom alla variabler i Java som är deklarerade att innehålla ett objekt är s.k. objektreferenser så är det en kopia på referensen som skickas till en metod. Via denna referens kan det refererade objektet påverkas (det är alltså referensen som överförs via värdeanrop och inte själva objektet). Exempel på detta kommer strax. Robert Jonsson Sida 9

I exemplet ovan skickas en heltalsvariabel med värdet 10 som ett argument till metoden nollstall(). Här är det en kopia på variabeln tal och dess värde som skickas till metoden (via värdeanrop). Parametervariabeln tal initieras till att innehålla värdet som skickats (d.v.s. 10). När sedan variabeln tal i metoden nollstall sätts till noll påverkar detta endast den lokala parametervariabeln, och inte variabeln tal i den anropade metoden (metoden main). Prova att öppna exemplet VardeAnrop.java i mina exempel och testkör. Robert Jonsson Sida 10

Exemplet ovan fungerar på liknande sätt som VardeAnrop, men här har vi en metod vars ena parameter är ett objekt av typen Person. Tanken är att vi har en metod där vi som parameter skickar ett Person-objekt samt en sträng med ett namn vi vill sätta på personen. När det gäller objekt som skickas som parameter till en metod är kopian och originalet en referens till samma objekt i minnet. Så det som överförs vid värdeanrop för ett objekt är alltså en kopia på referensen. I metoden bytnamn() lagras denna objektreferens i p. När vi sedan använder p för att byta namn så byter vi namn på objektet som p refererar till. I och med att originalet p1 refererar till samma objekt som kopian p är namnet bytt även på p1. Öppna exemplet ReferensAnrop.java för att prova detta. Robert Jonsson Sida 11

Det är möjligt att i metoddeklarationen ange att en parameter inte får modifieras i en metod (ges ett annat värde). Om ett argument skickas till en metod och man dels vill tydliggöra för anroparen att metoden inte modifierar parametern och dels få en kontroll av kompilatorn att så inte sker, så kan parametern deklareras som final. En sådan deklaration talar om att parametern när den väl har initieras är slutgiltig och att den således inte får eller kan modifieras. I exemplet ovan kommer vi att få ett kompileringsfel när vi försöker sätta nytt värde på parametervariablen x. Observera att när det är frågan om objektreferenser så kan vi fortfarande anropa metoder på objektet, t.ex. setnamn("stina"), och förändra värdet på eventuella instansvariabler objektet har. Däremot kan vi inte tilldela objektreferensen en referens till ett annat objekt (vilket är möjligt om inte final används). final kan också användas på instansvariabler och har då samma betydelse. D.v.s. efter att variabeln tilldelats ett värde kan detta värde inte förändras. Robert Jonsson Sida 12

Vi har nu tittat på hur vi kan skicka in värden till metoder,. Det är ibland även nödvändigt för metoder att sända tillbaka ett resultat. T.ex. kan en metod ta ett tal som parameter och utföra beräkningar på detta tal. När beräkningarna är gjorda vill vi returnera resultatet så att vi kan använda det beräknade värdet i resten av programmet. Som du kommer ihåg från genomgången av metoddeklarationen har alla metoder en returtyp. För metoder måste vi alltid ange en returtyp oavsett om metoden returnerar ett värde eller inte. För metoder som inte returnerar ett värde anger vi void som returtyp. I de exempel vi hittills har stött på så har metoderna inte returnerat något värde. Returtypen kan generellt sett delas upp i två olika typer. Antingen är returtypen en primitiv datatyp (dvs en int, double, char, boolean etc.) eller så är returtypen ett objekt av någon klass. Detta kan vara egendefinierade klasser (t.ex Person, Punkt etc.) eller någon av de fördefinierade klasser som följer med Java (t.ex. String, Button, Graphics etc.). Robert Jonsson Sida 13

När vi anropar en metod som returnerar ett värde så kommer själva metodanropet att få (innehålla, ersätta, tilldelas) det värde som returneras. Om vi t.ex. har en klass där det finns en metod med namnet settal() och en metod gettal() för att sätta/hämta värdet på en instansvariabel och exekverar följande programsatser obj.settal(10); obj.gettal(); kommer uttrycket obj.gettal() att tilldelas värdet 10 efter det att metoden gettal()har exekverats klart och returnerat sitt värde. Det returnerade värdet kan vi sen manipulera på samma sätt som andra variabler, vi kan skriva ut det i kommandofönstret med System.out.println(). Ett annat sätt vi kan använda värden som returneras är att tilldela den till en annan variabel. I exemplet i bilden med metoden gettal() kan vi tilldela det returnerade värdet till en variabel av typen int (heltal). // tilldelar variabeln i värdet som returneras av // metodanropet obj.gettal(),(vilket blir 10) int i = obj.gettal(); OBS!! Jämt när vi returnerar ett värde från en metod måste vi använda oss av nyckelordet return följt av det värde som ska returneras. Det värde som returneras måste även vara av samma typ som metodens returtyp. Robert Jonsson Sida 14

Låt oss nu utöka klassen Person från tidigare lektioner med följande: I stället för att en person har ett namn låter vi en person ha både ett för- och ett efternamn. Det kan även vara lämpligt att veta en persons ålder (vilket vi i och för sig kunnat räkna fram utifrån personnumret och aktuellt datum). Vidare utökar vi metoderna med set() och get()-metoder för att ändra dessa instansvariabler. Vi utökar även med metod för att sätta och hämta hela namnet på en gång. Set()-metoden kommer att ta två parametrar varav det första är förnamnet och den andra parametern är efternamnet. I exemplet Person2.java har jag gjort utökningen enligt ovan. Ta en titt på källkoden och titta framför allt på get()-metodernas uppbyggnad samt metoden setnamn() som nu tar två parametrar. Öppna även PersonTest2.java för att provköra exemplet. Robert Jonsson Sida 15

Det är möjligt att i en klass ha flera metoder med samma namn. Detta kallas att överlagra en metod, och leder då till att det finns flera implementationer (varianter) av samma metod (det är egentligen fråga om olika metoder men med samma namn). Kravet vid överlagring är att varje implementation antigen har olika antal parametrar eller olika typ på parametrarna. Returtypen måste vara samma för alla varianter. När ett anrop görs på metodens namn anropas den implementation som passar bäst för de argument som angivits i anropet. Det är viktigt att samtliga implementationer utför i princip samma sak. D.v.s. betydelsen av vad metoden gör ska bibehållas hos samtliga implementationer av de överlagrade metoderna. Det finns ingen begränsning av hur många överlagrade metoder vi kan ha. Huvudsaken är att signaturen är olika mellan de olika varianterna, annars säger kompilatorn ifrån. Robert Jonsson Sida 16

Här är ett exempel på en metod som överlagrats. Det finns tre varianter av samma metod, tre metoder med samma namn, men där signaturen är olika. Alla metoder har samma betydelse nämligen att skriva ut en text. Första metoden har en parameter och skriver enbart ut texten som anges i variabeln s, andra metoden har två parametrar och skriver ut texten i en viss färg och den sista metoden har tre parametrar och skriver ut texten i en viss färg och med en viss font (teckensnitt/stil). Här skiljer sig signaturen åt genom att antalet parametrar är olika. Vi skulle kunna ha ytterligare en metod skrivut() med bara en parameter, men där vi istället för String sätter int som typ (för att skriva ut ett heltal på skärmen). I exemplet Adderare2.java har jag utökat den ursprungliga Addera.java med överlagrade metoder så att vi kan addera två heltal med varandra, två decimaltal med varandra och ett decimaltal med ett heltal. I vår utökade version av Person.java med set()- och get()-metoder, samt uppdelningen av namnet till både för- och efternamn, kan det vara smidigt för användare av klassen att kunna sätta namnet på olika sätt. I Person2.java hade vi metoden setnamn(string f, String e) för att sätta både för- och efternamn samtidigt. Denna metod överlagras nu i Person3.java så att vi har en variant som inte tar några parametrar. Istället används i den metoden nu dialogrutor som frågar användaren efter det namn som personen ska ha. Notera vad utskriften för objektet okänd blir. För detta objekt sätts endast värden för vissa av instansvariablerna. Övriga instansvariabler tilldelas default-värden, vilka då? Robert Jonsson Sida 17

Vi har hittills skapat ett objekt och sen använt olika set()-metoder för att ge objektet lämpliga värden. Detta sätt att tilldela ett objekt sina värden är inte speciellt smidigt då det är lätt att glömma att sätta ett värde för en instansvariabel (och som då tilldelas ett default-värde). Det är även ganska jobbigt att använda set()-metoder om objektet har många instansvariabler vars värden ska sättas. I stället för att manuellt anropa varje set()- metod vore det smidigt om fanns ett sätt där vi kunde ge objektet dess värden i samband med skapandet av objektet. Och det finns det (vilken tur!). Konstruktorn är en speciell typ av metod som används just för tilldela objektet sina värden. Med konstruktorn initierar vi objektet med lämpliga startvärden direkt när objektet skapas. Som åtkomstmodifierare för en konstruktor sätter vi antingen public eller private (väldigt sällan private). En konstruktor saknar alltid returtyp, vilket innebär att vi inte kan anropa en konstruktor som en vanlig metod eftersom en sådan metod alltid har ett returvärde. En konstruktor måste även ha samma namn som klassen för annars är det ingen konstruktor. Tack vare konstruktorn kan vi garantera att ett objekt alltid initieras till lämpliga initialvärden. Om vi återgår till vår första klass (Punkt) så ser en konstruktor som inte har några parametrar ut så som bilden ovan visar, d.v.s. public punkt(). Robert Jonsson Sida 18

En konstruktor används för att skapa instanser (förekomster, objekt) av en klass. En konstruktor-deklaration ser precis ut som en metod-deklaration fast med skillnaden att konstruktorn måste ha samma namn som klassen och att den inte kan returnera ett värde. Därför anger vi ingen returtyp i konstruktor-deklarationen (inte ens void). Tillskillnad mot klassens instansvariabler och metoder så anses inte konstruktorn vara en medlem av klassen. Därför ärvs inte konstruktorn av klassens subklasser (mer om arv i kommande lektioner). Konstruktorn bör användas till att utföra nödvändiga initieringar av objektets variabler i samband med att objektet skapas. I vårt exempel med klassen Punkt vore det lämpligt att kunna tilldela instansvariablerna xkord och ykord lämpliga värden i samband med att ett objekt av klassen skapas. Istället för att använda set()-metoder för att sätta ett objekts initialvärden kan konstruktorn användas istället. Konstruktorn för vår klass Punkt skulle då ta två parametrar, en för x-koordinaten och en för y-koordinaten. Det vi sen gör i själva konstruktorn är att tilldela våra instansvariabler xkord och ykord värdet av de argument som skickades till konstruktorn, med andra ord samma funktion som set()- metoderna har. Fast nu sker det direkt när objektet skapas. På det här sättet har vi garanterat att ett objekt alltid har initierats med lämpliga värden, vilket förhindrar att vi jobbar med objekt som inte har initierats. Robert Jonsson Sida 19

I våra klasser har vi hittills inte skrivit någon egen konstruktor, men faktum är att alla klasser alltid har en konstruktor. Om vi för en klass inte skriver någon konstruktordeklaration kommer Java att automatiskt att tillhandahålla en default-konstruktor. Denna konstruktor tar inga parametrar och innehåller dessutom ingen kod. Om klassen är deklarerad som publik kommer också default-konstruktorn att vara publik och således vara åtkomlig för andra objekt att använda. Default-konstruktorns roll är helt enkelt att skapa en förekomst (ett objekt) av aktuell klass. Default-konstruktorn för vår Punkt-klass är en publik konstruktor utan paramentrar och utan kod. Precis som bilden ovan visar. Det förklarar varför den programsats vi använt hittills använt för att skapa Punkt-objekt (eller Person-objekt för den delen) är giltig. Det som skrivs efter operatorn new, d.v.s. Punkt(),är klassens default-konstruktor. Robert Jonsson Sida 20

Till skillnad mot metoder som kan anropas när som helst av vem som helst (i stort sett) kan konstruktorn endast anropas en gång och det är när objektet i fråga skapas. D.v.s. i samband med att nyckelordet new används. Precis som för metoder måste argumenten som skickas till konstruktorn exakt "matcha" parametrarna i konstruktordeklarationen. D.v.s. vi måste skicka med rätt antal och rätt typ i anropet när vi skapar ett objekt. Tidigare skapades ett Punkt-objekt (p1 i exemplen) med hjälp av defaultkonstruktorn och därefter användes metoder för att sätta punktens koordinater. I exemplet Punkt.java har vi nu en konstruktor som kan användas för att direkt initiera objektet. Försöker man nu skapa ett objekt som inte "matchar konstruktorns parametrar ges ett kompileringsfel. Observera att har vi skrivit en egen konstruktor i klassen så tillhandahålls inte längre någon default-konstruktor (vi kan dock själva skriva en konstruktor som inte tar några parametrar och som inte innehåller någon kod, men det sker inte automatiskt längre). Robert Jonsson Sida 21

I samtliga klasser (och dess metoder) finns det en speciell instansvariabel som heter this (finns alltid och är ett nyckelord). this är en objektreferens till det objekt som metoden anropats på (en s.k. självreferens). Denna självreferens kan användas på tre olika sätt: Oftast används den för att skicka en referens till det egna objektet som argument till ett annat objekt. Detta för att gör det möjligt med tvåvägs kommunikation mellan objekt. Hittills har vi enbart använt envägskommunikation där vi från ett objekt anropar ett annat objekt. Skickar vi med en självreferens kan den anropade metoden i sin tur göra anrop tillbaka. Vi kan också använda this för att från en konstruktor anropa en annan (överlagrad) konstruktor i samma klass. Ett sista sätt att använda this är för att skilja instansvariabler från lokala variabler med samma namn. this-referensen är inte tillgänglig i statiska metoder (förklaras snart) i en klass men kan användas i alla andra metoder. Robert Jonsson Sida 22

Precis som med metoder är det möjligt att överlagra konstruktorer. Här gäller samma krav för konstruktorerna som för överlagring av metoder. D.v.s. att varje implementation har olika antal parametrar eller olika typ på parametrarna (att signaturen skiljer sig åt). I exemplet i bilden har vi två stycken konstruktorer som tar antingen två eller inga parametrar. Beroende på om två eller inga argument anges när ett objekt skapas av klassen anropas alltså någon av dessa konstruktorer (den konstruktor som matchar bäst anropas). Notera att implementationen för ingen parametrar innehåller ett anrop av typen this(). Ett sådant anrop anropar en annan konstruktor i samma klass, i detta fall kommer alltså konstruktorn för inga parametrar att anropa den som tar två parametrar (vi skickar med två heltal i this-anropet). I den överlagrade konstruktorn (som har två parametrar) ges även exempel på en annan användning av självreferensen this. Här har parametrarna samma namn som klassens instansvariabler. För att i konstruktorn kunna skilja dessa variabler åt använder vi this.namn_på_instansvariabel för att referera till instansvariabeln. Detta gäller även i vanliga metoder när parametrarna har samma namn som instansvariablerna. Det är inget krav att alla överlagrade konstruktorer leder fram till samma slutgiltiga konstruktor, men det är en ganska vanligt förekommande konstruktion att några konstruktorer innehåller default-värden för argumenten i en annan konstruktor. this är som sagt ett nyckelord i Java och används för att inom ett objekt referera till sig själv. this representerar alltså en referens till det egna objektet och genom att anropa this med en serie argument anropas en konstruktor i objektets egen klass. Det finns ingen regel för hur många konstruktorer vi ska skriva för en klass utan vi får helt enkelt sätta oss ner och tänka igenom vilka olika sätt som kan vara bra att kunna skapa ett objekt på. I exemplet Person4.java har jag utökat klassen med tre överlagrade konstruktorer som på ett eller annat sätt sätter värden på objekten i samband med skapandet. Notera användandet av this. Robert Jonsson Sida 23

En instansvariabel som deklarerats med modifieraren final kan, efter att det har tilldelats ett värde, inte förändra värdet senare i programmet. D.v.s. det är en konstant instansvariabel som alltid kommer att ha det värde det initialt tilldelats. Värdet för en instansvariabel satt till final sätts antingen direkt vid deklarationen (vanligast) eller så tilldelas instansvariabeln ett värde i konstruktorn (som sedan inte kan förändras i några andra metoder). Om klassen har flera konstruktorer måste instansvariabeln ges ett värde i samtliga konstruktorer. Värdet som tilldelas en variabel deklarerad som final behöver inte vara en konstant utan kan beräknas eller passas in till konstruktorn som en parameter. Robert Jonsson Sida 24

Låt säga att vi utökar vår klass Punkt med konstanter för en punkts storlek (diameter som sen inte kan ändras) och de maximala värden en punkt kan ha på sin x- och y- koordinat. En konstant måste som nämndes tidigare antingen tilldelas ett värde direkt vid deklarationen, vilket är fallet för MAX_X och MAX_Y. Görs ingen initiering av konstanten vid deklarationen så måste vi göra det i alla konstruktorer (eller skicka med ett värde för konstanten i ett anrop av this()). Notera att namnet på konstanter normalt skrivs med enbart STORA BOKSTÄVER. Inför de ändringar som visas i bilden ovan i Punkt.java. Prova därefter att i någon metod försöka sätta ett nytt värde på någon av konstanterna. Robert Jonsson Sida 25

En medlem i en klass (en instansvariabel eller en metod) kan definieras med modifieraren static. Den blir då en statisk medlem som endast finns i ett exemplar för klassen, oavsett hur många objekt som skapas av klassen. Detta till skillnad mot icke-statiska instansvariabler då ju ett nytt exemplar av varje instansvariabel skapas för varje objekt som skapas. En statisk medlem implementerar något som lagras och används på klassnivå istället för objektnivå. Man kan säga att statiska medlemmar är gemensamma för (delas av) alla objekt som skapats av klassen. Ges en statisk instansvariabel ett nytt värde för något av de skapade objekten får alla andra objekt detta värde. Om vi i Punkt-klassen vill räkna hur många Punkt-objekt som skapats i en applikation kan detta göras med en statiskt instansvariabel. I exemplet i bilden ovan så initieras den statiska klassvariabeln antalpunkter till 0. Denna initiering görs endast en gång i en applikation och görs redan vid uppstarten av applikationen (innan några objekt av klassen skapats). Konstruktorn för klassen räknar sedan upp variabeln varje gång den anropas, d.v.s. varje gång ett objekt av klassen skapas. Eftersom klassvariabler delas mellan samtliga objekt av klassen så är den också åtkomlig från samtliga objekt (av aktuell klass). Hade antalpunkter inte varit deklarerade som statisk hade varje objekt haft ett eget exemplar av denna variabel och i samband med att objektet skapas hade det initierats till 0. Efter att konstruktorn exekverat klart hade alla objekt haft ett eget exemplar av antalpunkter satt till värdet 1. Genom att den nu i stället är statisk så blir den gemensam för samtliga objekt och lagras i stället på klassnivå. Robert Jonsson Sida 26

En statisk metod, en s.k. klassmetod, har den begränsningen att den endast kan referera klassvariabler, d.v.s. instansvariabler som också är deklarerade som statiska (static). Det går alltså inte i en statisk metod att referera till vanliga instansvariabler i klassen. En klassmetod saknar också this-referensen för att referera till ett aktuellt objekt (eftersom en statisk metod deklarerats på klassnivå i stället för på objektnivå och tillhör alla objekt och inte ett speciellt enskilt objekt). En statisk metod (klassmetod) kan endast anropa andra statiska metoder. Det innebär t.ex. att om vi från main()-metoden (som är statisk) vill anropa en annan metod i samma klass som main(), måste även den andra metoden deklareras som static. Fördelen med en statisk metod är att den kan anropas genom att endast ange klassens namn vid anropet, något objekt av klassen behöver inte finnas tillgänglig. I exemplet Person5.java har jag utökat klassen med en statisk instansvariabel för att räkna hur många objekt som skapas av klassen. Det finns även en metod som returnerar värde på den statiska instansvariabeln. Robert Jonsson Sida 27

I den genomgång av Javaspråkets som gjordes nämnde jag kort vad arv är. Med arvs-mekanismen kan vi från en befintlig klass skapa nya klasser som ärver sina egenskaper från den andra klassen. I Java härstammar alla klasser från en och samma grundklass, d.v.s. alla klasser ärver sina egenskaper från en annan klass. Denna klass heter Object och är vad som kallas en superklass till alla övriga klasser i Java. Klassen Object innehåller ett par metoder som alla klasser måste ha och en av dessa är metoden tostring(). Tips! Ta en titt i Javas API för klassen Object och se vilka fler metoder som finns. I och med att alla klasser ärver sina egenskaper från Object innebär det att alla klasser har en tostring()-metod trots att vi inte skrivit någon sådan metod själv i våra klasser. Denna metod används för att representera information om objektet som en sträng, d.v.s. metoden returnerar en sträng innehållandes en s.k. strängrepresentation av objektet. Som default returneras något som kan liknas vid en adress när vi anropar denna metod och därför bör vi alltid omdefiniera tostring()-metoden i våra egna klasser. Du kan prova att ändra i PersonTest5.java så att du på något av objekten anropar metoden tostring() och skriva ut det returnerade värdet. T.ex: String s = p1.tostring(); System.out.println(s); System.out.println(p2.toString()); System.out.println(p3); I vår klass Punkt är en lämplig representation av ett punkt-objekt dess x- och y-koordinater. Så lämpligen returnerar vi objektets koordinater i ett snyggt format (se bilden). För ett Person-objekt kan en lämplig representation vara förnamnet och efternamnet. Det är helt och hållet upp till utvecklaren att tänka igenom på vilket sätt ett objekt av klassen kan representeras som en sträng. I exemplet Person6.java och PersonTest6.java har jag överlagrat, som det heter, metoden tostring() för att returnera en strängrepresentation av ett Person-objekt. Robert Jonsson Sida 28

Bortsett från String (som är en klass) så har vi uteslutande använd de primitiva typerna som instansvariabler i våra klasser. Det är dock ytterst sällan vi enbart använder primitiva typer utan ofta används även andra klasser som typ på våra instansvariabler. Dessa klasser kan vara både egendefinierade klasser och färdiga klasser från det standardbibliotek som medföljer. Principen är dock den samma. Vår tidigare Person-klass innehåller information om en persons för- och efternamn. Det kan vara praktiskt att låta namnet representeras av en egen klass i stället. Klassen döper vi till Namn och den kommer att innehålla information om för- och efternamn (se UML i bilden). Vår nya klass Namn kommer att få två konstruktorer. En där vi anger för- och efternamn (två parametrar)och en där default-värden kommer att sättas (inga parametrar). Utöver konstruktorerna skriver vi diverse set() och get() metoder för att manipulera instansvariablerna fornamn och efternamn. I Person-klassen kan vi nu ersätta de båda gamla instansvariablerna fornamn och efternamn med en ny instansvariabel som är av typen Namn (som ju innehåller både ett förnamn och efternamn). För att enkelt kunna skapa objekt av Person lägger vi till konstruktorer som tar ett Namn-objekt som parameter, vilket innebär att för att kunna skapa ett Person-objekt måste vi först skapa ett Namnobjekt som vi skickar med som argument när vi skapar ett Person-objekt. Precis som vanligt har vi set() och get()metoder för alla instansvariabler i klassen. Metoden getnamn() kommer vi att skriva om så att den returnera ett objekt av typen Namn i stället för strängar med för- och efternamn som tidigare. Vill vi ta reda på personens för- och efternamn måste vi först anropa getnamn() för att få personens Namn-objektet. På detta objekt måste vi sen anropa metoderna getfornamn() och getefternamn(). Detta är inte speciellt smidigt så därför lägger vi till metoden getnamnasstring() som returnerar förnamnet och efternamnet direkt som en sträng. Lägg märke till att den statiska metoden visas i UML genom ett streck under sig. Robert Jonsson Sida 29

Dokumentationskommentaren används för automatgenererad dokumentation. I JDK finns ett verktyg som heter javadoc, som utifrån kod skriven i Java kan producera dokumentationen i HTML-format. På så sätt kan man hålla ihop dokumentationen av en klass med koden för en klass. En dokumentationskommentar måste finnas omedelbart före den klassdeklaration eller klassmedlem som ska dokumenteras. Det genererade resultatet blir i form av en HTML-fil där metodnamn blir hyperlänkar till mer information i form av de kommentarer som knutits till metoden. Hela den API som finns för Java är gjord med javadoc och dokumentationskommentarer. Robert Jonsson Sida 30

För alla dokumentationskommentarer gäller det att första meningen ska vara en summering av det som dokumenteras. Därefter kan man skriva en mer utförlig beskrivning. För klasser ska man ange vilken författaren av klassen är samt vilken version det är. Detta gör vi genom att använda taggarna @author och @version. Det normala är att vi endast dokumenterar publika medlemmar. Så privata instansvariabler är något vi vanligtvis inte dokumenterar. Jag har enbart gjort det i bilden ovan för demonstrativt syfte. Robert Jonsson Sida 31

För konstruktorer och metoder gäller även här att första meningen ska vara en sammanfattning. För metoder ska vi dokumentera eventuella parametrar och returvärden. Parametrar dokumenterar vi med taggen @param enligt följande modell: @param namn_på_parameter en_kort_beskrivning_av_parametern Har metoden flera parametrar skrivs en @param för varje parameter Returvärden dokumeterar vi med taggen @return enligt följande modell: @return en_beskrivning_av vad_som_returneras Saknas returvärde för en metod (d.v.s. void anges) utesluter vi helt användandet av taggen @return. Robert Jonsson Sida 32

Utifrån de dokumentationskommentarer vi skrivit i källkoden kan sen verktyget javadoc, som följer med installationen av JDK, generera HTML-filer. För att på smidigaste sättet gör detta samlas alla källkodsfiler (som vi vill ska ingå i dokumentationen) i en och samma mapp. Därefter öppnar vi ett kommandofönster och byter katalog till den katalog där våra källkodsfiler ligger. Därefter skriver vi javadoc följt av de filer vi vill ska ingå i dokumentationen. För att generera dokumentation för alla filer i katalogen anger vi *.java. javadoc *.java Efter en stund har ett antal olika html-filer skapats och vi kan titta igenom vår dokumentation genom att öppna filen index.html i en webbläsare. Ta nu en titt på hur jag byggt upp klasserna Namn.java, Person.java och PersonTest.java. Det är viktigt att du får bra grepp på hur vi använder andra klasser i en klass så var extra observant på hur klassen Namn används i Person och hur vi på olika sätt sätter namn och returnerar namn i Person. Jag har även dokumenterat alla publika medlemmar i klasserna Namn och Person. Efter att du har provat klasserna kan du kopiera Person.java och Namn.java till en tom katalog och generera dokumentationen. Robert Jonsson Sida 33