Objekt och referenser 9 October 2003 1
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”;
}
// överlagrad konstruktor
public Person(String n, String a, String p) { namn = n;
adress = a;
personnummer = p;
}
public int hämtaNamn() { return namn;
}
public void bytNamn(String nyttNamn) { namn = nyttNamn;
} ...
}
Objekt och referenser 9 October 2003 2
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 konstruk- torer 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 main- metod.
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 primi- tiva typerna (int, double mfl) och objekt.
int tal; // vi har ett heltal Person lisa; // vi har inte en person
// men vi kan skapa en senare
Vi kallar variabler som hugobald och lisa för refer- enser. 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
hugobald.bytNamn(“Hugo Bardun”);
Så kommer datorn att protestera och säga att du kan ju inte byta namn innan du skapat personen, refer- ensen är null.
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 kon- struktorer. Slutresultatet blir ju två olika objekt som är exakt lika bortsett från värdet av instansvaria- blerna, (namn, adress och personnummer).
Objekt och referenser 9 October 2003 5
Vi kan nu se det så här
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”);
Ger instansvariabeln namn ett nytt värde.
lisa
Lisa Nilsson Storgatan
790212-2342
Objekt och referenser 9 October 2003 6
Nu gör jag följande:
Person stina; // en referens stina = lisa; // lika som lisa
Nu har vi skapat en referens till. Sen har vi tilldelat lisas värde tills stina.
Nu kan vi göra:
Std.out.println(“Du heter: “ + stina.hämtaNamn());
Svaret blir:
Lisa Svensson
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());
Datorn säger
Du heter: Stina Karlsson
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
lisa
stina
Lisa Svensson Storgatan 790212-2342
Objekt och referenser 9 October 2003 9
När du gör stina = lisa;
så får du INTE nåt nytt objekt. Du säger bara att sky- lten 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”...
Då får vi ett nytt objekt som skylten stina pekar ut.
Flera referenser till samma objekt kan vara använd- bart men kan ju också vålla förvirring.
Objekt och referenser 9 October 2003 10
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:
filip
hugo
Filip Karlsson
Hugo Bardun
Om vi nu gör filip = hugo;
så får vi:
Båda refererar samma objekt. Det första är det ingen filip
hugo
Filip Karlsson
Hugo Bardun
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 refer- enserna.
dvs satsen if (lisa == stina) ...
Undersöker INTE om objekten är lika, utan bara om
“skyltarna” lisa och stina pekar ut samma objekt.
Objekt och referenser 9 October 2003 13
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 och referenser 9 October 2003 14
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, jämför likhet
compareTo, undersöker ordning
Exempel
String s = “Nisse”;
String t = “Nis”;
t =t + “se”;
if (s.equals(t)) Std.out.println(“Lika”);
else Std.out.println(“Olika”);
Ger garanterat utskriften Lika.
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 all- tid referera andra objekt via en referens och sig själv via namnet this.
Exempelvis kan man göra (men egentligen onödigt) // överlagrad konstruktor
public Person(String n, String a, String p) { this.namn = n;
this.adress = a;
this.personnummer = p;
}
this.namn betyder alltså instansvariabeln mitt namn.
Objekt och referenser 9 October 2003 17
Man ser ganska ofta // överlagrad konstruktor
public Person(String namn, String adress, String personnummer) { this.namn = namn;
this.adress = adress;
this.personnummer = personnummer;
}
dvs parametrarna har samma namn som instansvar- iablerna.
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 instansvaria- bel. Den måste jag referera genom this i detta fall.
Då blir det alltid instansvariabeln.
Objekt och referenser 9 October 2003 18
This kan användas på flera sätt.
public Person() {
this(“NN”, ““, “000000-0000”);
}
// överlagrad konstruktor
public Person(String n, String a, String p) { namn = n;
adress = a;
personnummer = p;
}
Nu kan vi spara arbete genom att låta en konstruk- tor använda en annan. Här kommer den första att använda den andra konstruktorn och vi spar skriv- arbete.
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 klassvar- iabler. I Java anges sådana med attributet static.
Exempelvis kan vi införa ett medlemsnummer i per- sonklassen som vi vill ska vara unikt för varje per- son. 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++;
Objekt och referenser 9 October 2003 21
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.
Objekt och referenser 9 October 2003 22
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 }
Här är ränteSats deklarerad som statisk vilket bety- der att den är gemensam för alla konton som vi ska- par. 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 25
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.
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 26
Vår klass har två andra klasser som instansvariabler.
Det är huvudtanken med objekt, att man ska kom- binera dem till mer avancerade saker. Blir ganska enkelt och överskådligt.