Objekt och referenser Antag att vi har följande enkla klass: public class Person { private String namn; private String adress; private String personnummer; public Person() { namn = NN ; adress = ; personnummer = 000000-0000 ; namn = n; adress = a; personnummer = p; public int hämtanamn() { return namn; Vi har då en ritning för hur en person ser ut. Vi kan sedan skapa objekt av typen Person. Då måste vi deklarera en variabel av typ Person och använda new. Då kommer någon av våra konstruktorer att användas. Var gör vi detta? I nåt javaprogram, egentligen var som helst. Vill vi bara testa så är det ofta i en mainmetod. Person hugobald; Vi har nu en variabel av typ Person. Vi har INTE något objekt ännu, dvs ingen person. Det vi sagt är att variabeln hugobald kan bli en person. Detta är en fundamental skillnad mellan de primitiva typerna (int, double mfl) och objekt. int tal; Person lisa; // vi har ett heltal // vi har inte en person // men vi kan skapa en senare public void bytnamn(string nyttnamn) { namn = nyttnamn;... Objekt och referenser 9 October 2003 1 Objekt och referenser 9 October 2003 2 Vi kallar variabler som hugobald och lisa för referenser. En referens är något som kan peka ut något annat, en sorts skylt. I detta fall kan de peka ut ett personobjekt. Vad pekar hugobald på efter att vi gjort Person hugobald; Ingenting, det är en nollreferens och den har det speciella värdet null. Försöker jag nu göra Eftersom det finns två konstruktorer kan jag skapa personer på två olika sätt. hugobald = new Person(); // standard lisa = new Person( Lisa Nilsson, Storgatan, 790212-2342 ); Båda skapar personobjekt men använder olika konstruktorer. Slutresultatet blir ju två olika objekt som är exakt lika bortsett från värdet av instansvariablerna, (namn, adress och personnummer). hugobald.bytnamn( Hugo Bardun ); Så kommer datorn att protestera och säga att du kan ju inte byta namn innan du skapat personen, referensen är null. Objekt och referenser 9 October 2003 3 Objekt och referenser 9 October 2003 4
Vi kan nu se det så här Nu gör jag följande: lisa Lisa Nilsson Storgatan 790212-2342 Person stina; stina = lisa; // en referens // lika som lisa Nu har vi skapat en referens till. Sen har vi tilldelat lisas värde tills stina. Nu kan vi göra: Variabeln lisa refererar ett objekt av typen Person. Själva objektet heter egentligen ingenting. Vill du använda objektet görs det via referensen. lisa.bytnamn( Lisa Svensson ); Std.out.println( Du heter: + stina.hämtanamn()); Svaret blir: Lisa Svensson Ger instansvariabeln namn ett nytt värde. Objekt och referenser 9 October 2003 5 Objekt och referenser 9 October 2003 6 Sen vill vi döpa om personen stina.nyttnamn( Stina Karlsson ); Std.out.println( Du heter: + stina.hämtanamn()); Ger utskriften: Du heter: Stina Karlsson Nu kollar vi vad lisa heter: Std.out.println( Du heter: + lisa.hämtanamn()); När vi döpte om stina så fick tydligen lisa också ett nytt namn??? Det beror på att vi arbetar med referenser. När vi gjorde stina = lisa; så fick vi Datorn säger Du heter: Stina Karlsson lisa stina Lisa Svensson Storgatan 790212-2342 Objekt och referenser 9 October 2003 7 Objekt och referenser 9 October 2003 8
När du gör stina = lisa; så får du INTE nåt nytt objekt. Du säger bara att skylten stina ska peka på samma sak som skylten lisa. Du får två referenser till samma objekt. För att få ett nytt objekt så använder vi new. stina = new Person( Stina Karlsson... Om vi gör så här då? Person filip = new Person( Filip Karlsson, Storgatan, 650912-2312 ); Person hugo = new Person( Hugo Bardun, Kungsgatan, 780423-1234 ); Då blir det ju så här: Då får vi ett nytt objekt som skylten stina pekar ut. Flera referenser till samma objekt kan vara användbart men kan ju också vålla förvirring. filip hugo Filip Karlsson Hugo Bardun Objekt och referenser 9 October 2003 9 Objekt och referenser 9 October 2003 10 Om vi nu gör filip = hugo; så får vi: Det här betyder också att om vi försöker jämföra objekt så är det INTE objekten vi jämför utan referenserna. dvs satsen filip hugo Filip Karlsson Hugo Bardun if (lisa == stina)... Undersöker INTE om objekten är lika, utan bara om skyltarna lisa och stina pekar ut samma objekt. Båda refererar samma objekt. Det första är det ingen som refererar. Det är borttappat. Eftersom det inte heter nåt kan vi inte hitta det. Det kommer att tas bort automatiskt av skräpsamlaren (garbage collector). Objekt och referenser 9 October 2003 11 Objekt och referenser 9 October 2003 12
Eftersom strängar är objekt så blir det samma sak där. String s = Nisse ; String t = Nis ; t =t + se ; if (s == t) Std.out.println( Lika ); else Std.out.println( Olika ); Testar inte om s och t är lika utan testar om s och t pekar ut samma strängobjekt. De är olika här, men strängreferenser kan ibland bli lika om Java är smart. Objekt har ju inte någon ordningsrelation. Hur vet vi om ett personobjekt är mindre än nåt annat objekt? Det gör att <, > mfl inte kan användas på strängar eller andra typer av objekt. För strängar använder vi metoderna equals, compareto, Exempel String s = Nisse ; String t = Nis ; jämför likhet undersöker ordning t =t + se ; if (s.equals(t)) Std.out.println( Lika ); else Std.out.println( Olika ); Ger garanterat utskriften Lika. Objekt och referenser 9 October 2003 13 Objekt och referenser 9 October 2003 14 String s = Nisse ; String t = Putte ; if (s.compareto(t) < 0 ) Std.out.println( s före t ); else if (s.compareto(t) == 0) Std.out.println( Lika ); else Std.out.println( s efter t ); Med före och efter menas i bokstavsordning, eller egentligen i teckenordning. I detta exempel skriver datorn s före t Objekt har ju egentligen inget namn men de kan alltid referera andra objekt via en referens och sig själv via namnet this. Exempelvis kan man göra (men egentligen onödigt) this.namn = n; this.adress = a; this.personnummer = p; this.namn betyder alltså instansvariabeln mitt namn. Objekt och referenser 9 October 2003 15 Objekt och referenser 9 October 2003 16
Man ser ganska ofta public Person(String namn, String adress, String personnummer) { this.namn = namn; this.adress = adress; this.personnummer = personnummer; dvs parametrarna har samma namn som instansvariablerna. Regel: När du använder en variabel så väljer Java den som den senast hittade. Efterson parametrarna hittas sist så kommer exempelvis namn att vara parameterns värde, dvs önskat namn, inte objektets instansvariabel. Den måste jag referera genom this i detta fall. Då blir det alltid instansvariabeln. This kan användas på flera sätt. public Person() { this( NN,, 000000-0000 ); namn = n; adress = a; personnummer = p; Nu kan vi spara arbete genom att låta en konstruktor använda en annan. Här kommer den första att använda den andra konstruktorn och vi spar skrivarbete. Objekt och referenser 9 October 2003 17 Objekt och referenser 9 October 2003 18 En klass definierarju instansvariabler. Varje objekt som skapas får ju en egen uppsättning av dessa. Det ger ju möjlighet att ge varje person ett eget namn, en egen adress så vidare. Ibland vill man ha saker som är gemensamma för alla objekt av en viss typ. Sådana kallas för klassvariabler. I Java anges sådana med attributet static. Exempelvis kan vi införa ett medlemsnummer i personklassen som vi vill ska vara unikt för varje person. Då skapar vi dels en instansvariabel i klassen som är själva numret, dels en klassvariabel som vi hämtar numret från. public class Person { private String namn; private String adress; private String personnummer; private int medlemsnummer; private static int sekvensnummer = 1; public Person() { namn = NN ; adress = ; personnummer = 000000-0000 ); medlemsnummer = sekvensnummer; sekvensnummer++; namn = n; adress = a; personnummer = p; medlemsnummer = sekvensnummer; sekvensnummer++; Objekt och referenser 9 October 2003 19 Objekt och referenser 9 October 2003 20
Varje personobjekt hämtar nu sitt medlemsnummer från klassvariabeln sekvensnummer. Sedan ökas sekvensnumret, vilket gör att nästa objekt får ett nytt medlemsnummer. Klassvariabeln sätts till värdet 1 när klassen skapas, dvs en bara gång. Ett annat exempel kan vara public class Konto { private static double räntesats = 3.5; private String innehavare; private String kontonummer; private double saldo; public Konto () { this( NoName, 00000-000,0); public Konto(String i, String k, double s) { innehavare = i; kontonummer = k; saldo = s; public double hämtaräntesats() { return räntesats; public void ändraräntesats(double nyr) { räntesats = nyr; flera metoder Objekt och referenser 9 October 2003 21 Objekt och referenser 9 October 2003 22 Här är räntesats deklarerad som statisk vilket betyder att den är gemensam för alla konton som vi skapar. Den kan naturligtvis hämtas och ändras som andra instansvariabel, men om du ger den ett nytt värde så kommer det att gälla för alla konton. Saldo m. fl. gäller ju bara just detta konto. Objekt avbildar olika detaljer i en mer eller mindre verklig värld. Genom sina metoder kan vi få dem att utföra någon form av arbete. Tanken med detta är att man ska använda objekt som byggstenar för att skapa mera komplexa objekt som beskriver mer avancerade saker. Objekt och referenser 9 October 2003 23 Objekt och referenser 9 October 2003 24
Om vi exempelvis driver bankverksamhet kan vi skapa ett objekt som innehåller både en person och ett konto. Då får vi ett mer komplext objekt, byggt av enkla byggklotsar. Vår klass har två andra klasser som instansvariabler. Det är huvudtanken med objekt, att man ska kombinera dem till mer avancerade saker. Blir ganska enkelt och överskådligt. public class Kund { Person kund; Konto konto; public Kund(String namn, String adress, String personnummer, String kontonummer, double saldo) { kund = new Person(namn, adress, personnummer); konto = new Konto(namn, kontonummer, saldo); public String hämtanamn() { return kund.hämtanamn(); public void bytnamn(string nyttnamn) { kund.bytnamn(nyttnamn); konto.bytnamn(nyttnamn); Objekt och referenser 9 October 2003 25 Objekt och referenser 9 October 2003 26