Enkle objekter

• Enkle data-orienterte objekter
– – – – – felt instansiering navigering mellom objekter enkle (instans)metoder toString()-metoden

1

Hvordan knytte sammen data som utgjør en enhet?
• Objekter løser et generelt problem: Hvordan knytte sammen data, som utgjør en enhet Hal.. Tro. 115 213 • Sammenhørende data hører sammen med tabeller
– String[] navnetabell = {”Hallvard”, ”Trond”}; int[] kontornr = {115, 213};

• Vi trenger noe annet enn tabeller, som kan holde på ulike typer data på én gang!
2

Objekter
• Objekter kan samle data av ulike typer, på samme måte som tabeller kan samle data av samme type, men
– objekter har navngitte felt med verdier av definerte typer, istedenfor heltallsindekser som tabeller – objekter ligner på ark (eller visittkort), med feltene som variabler
Ansatt String navn = int kontor =
3

Objekter
• Objekter brukes når
– et fenomen kan beskrives med data som hører sammen (over tid) – prosesser har behov for å behandle data som én enhet – det finnes mange konkrete og gjerne observerbare ”ting” som har essensielle strukturelle likheter
• alle X har Y • når man gjør Z trenger man en X

• Terminologi
– Begrepet klasse har flere betydninger
• Strukturen som er felles for alle instanser av et fenomen • Settet med instanser som har essensielle likheter • Java-mekanisme for å knytte data (og metoder) sammn

– Begrepet objekt eller instans brukes om
• Én bestemt ”ting” med en viss struktur og et konkret/spesifikt innhold

• Eksempel:
– Fenomenet ansatt er noe generelt med faste data knyttet til seg: en klasse – Dataene som beskriver den bestemte ansatte Hallvard, rom 115: et objekt
4

Objekter
• Eksempel:
– En klasse: Fenomenet ansatt er noe generelt, som knytter samme spesifikke data, et navn og et romnr.:
Ansatt String navn int kontor

– Et objekt: Dataene som beskriver den bestemte ansatte Hallvard, rom 115
5

#1: Ansatt String navn = ”Hallvard” int kontor = 115

instans av

Eksempler: Kurs
• kurskode • navn • fagansvarlig
Kurs String kode String navn String faglærer #1: Kurs String kode = ”TDT4100” String navn = ”Objekt-orientert programmering” String faglærer = ”Hallvard Trætteberg”

Noen problemer med denne ”modellen”?
6

Eksempler: CD-spor
• navn • lengde • pause
Spor String navn int lengde int pause #1: Spor String navn = ” The Kids are on High Street” int lengde = 286 int pause = 3

Noen problemer med denne ”modellen”?
7

Objekter
• En klasse deklarerer strukturen til fenomenet, dvs. dataene som knyttes sammen • Eksempel (i Ansatt.java): Ansatt
– public class Ansatt { public String navn; public int kontor; } String navn = int kontor =

• Ansatt-ark (kalles instanser) lages med new Ansatt() • Felt leses og endres med .-notasjonen
– Ansatt ansatt = new Ansatt(); – ansatt.navn = ”Hallvard” – if (ansatt1.navn == ansatt2.navn) { ... }
8

Objekter
• Eksempel: // i Ansatt.java public class Ansatt { public String navn; public int kontor; } // i Hovedprogram.java public class Hovedprogram { public static void main(String[] args) { Ansatt a1 = new Ansatt(); a1.navn = ”Hallvard”; a1.kontor = 115; Ansatt a2 = new Ansatt(); a2.navn = ”Trond”; a2.kontor = 213; System.out.println(a1.navn + ” sitter på ” + a1.kontor); System.out.println(a2.navn + ” sitter på ” + a2.kontor); } }
String[] args

9

Objekter
• Eksempel: // i Ansatt.java public class Ansatt { public String navn; public int kontor; } // i Hovedprogram.java public class Hovedprogram { public static void main(String[] args) { Ansatt a1 = new Ansatt(); a1.navn = ”Hallvard”; a1.kontor = 115; Ansatt a2 = new Ansatt(); a2.navn = ”Trond”; a2.kontor = 213; System.out.println(a1.navn + ” sitter på ” + a1.kontor); System.out.println(a2.navn + ” sitter på ” + a2.kontor); } } #1: Ansatt
String[] args Ansatt a1 = String navn = int kontor = 0

10

Objekter
• Eksempel: // i Ansatt.java public class Ansatt { public String navn; public int kontor; } // i Hovedprogram.java public class Hovedprogram { public static void main(String[] args) { Ansatt a1 = new Ansatt(); a1.navn = ”Hallvard”; a1.kontor = 115; Ansatt a2 = new Ansatt(); a2.navn = ”Trond”; a2.kontor = 213; System.out.println(a1.navn + ” sitter på ” + a1.kontor); System.out.println(a2.navn + ” sitter på ” + a2.kontor); } } #1: Ansatt
String[] args Ansatt a1 = String navn = ”Hallvard” int kontor = 0

11

Objekter
• Eksempel: // i Ansatt.java public class Ansatt { public String navn; public int kontor; } // i Hovedprogram.java public class Hovedprogram { public static void main(String[] args) { Ansatt a1 = new Ansatt(); a1.navn = ”Hallvard”; a1.kontor = 115; Ansatt a2 = new Ansatt(); a2.navn = ”Trond”; a2.kontor = 213; System.out.println(a1.navn + ” sitter på ” + a1.kontor); System.out.println(a2.navn + ” sitter på ” + a2.kontor); } } #1: Ansatt
String[] args Ansatt a1 = String navn = ”Hallvard” int kontor = 115

12

Objekter
• Eksempel: // i Ansatt.java public class Ansatt { public String navn; public int kontor; } // i Hovedprogram.java public class Hovedprogram { public static void main(String[] args) { Ansatt a1 = new Ansatt(); a1.navn = ”Hallvard”; a1.kontor = 115; Ansatt a2 = new Ansatt(); a2.navn = ”Trond”; a2.kontor = 213; System.out.println(a1.navn + ” sitter på ” + a1.kontor); System.out.println(a2.navn + ” sitter på ” + a2.kontor); } } #1: Ansatt
String[] args Ansatt a1 = Ansatt a2 = String navn = ”Hallvard” int kontor = 115 #2: Ansatt String navn = int kontor = 0

13

Objekter
• Eksempel: // i Ansatt.java public class Ansatt { public String navn; public int kontor; } // i Hovedprogram.java public class Hovedprogram { public static void main(String[] args) { Ansatt a1 = new Ansatt(); a1.navn = ”Hallvard”; a1.kontor = 115; Ansatt a2 = new Ansatt(); a2.navn = ”Trond”; a2.kontor = 213; System.out.println(a1.navn + ” sitter på ” + a1.kontor); System.out.println(a2.navn + ” sitter på ” + a2.kontor); } } #1: Ansatt
String[] args Ansatt a1 = Ansatt a2 = String navn = ”Hallvard” int kontor = 115 #2: Ansatt String navn = ”Trond” int kontor = 0

14

Objekter
• Eksempel: // i Ansatt.java public class Ansatt { public String navn; public int kontor; } // i Hovedprogram.java public class Hovedprogram { public static void main(String[] args) { Ansatt a1 = new Ansatt(); a1.navn = ”Hallvard”; a1.kontor = 115; Ansatt a2 = new Ansatt(); a2.navn = ”Trond”; a2.kontor = 213; System.out.println(a1.navn + ” sitter på ” + a1.kontor); System.out.println(a2.navn + ” sitter på ” + a2.kontor); } } #1: Ansatt
String[] args Ansatt a1 = Ansatt a2 = String navn = ”Hallvard” int kontor = 115 #2: Ansatt String navn = ”Trond” int kontor = 213

15

Referanser til objekter
• Klassenavn kan/må brukes i deklarasjoner
– Ansatt a = new Ansatt(); // a kan ikke referere til noe annet enn Ansatt-instanser

• Variabler, parametre og felt kan referere til objekter
– void setNavn(Ansatt a, String s) { a.navn = s; }

• Metoder kan returnere objekter
– Ansatt lavesteKontornr(Ansatt a1, Ansatt a2) { return (a1.kontor < a2.kontor ? a1 : a2); }

• Flere variabler kan referere til samme objekt
– Ansatt a1 = new Ansatt(); a1.navn = ”Hallvard”; Ansatt a2 = a1; a2.navn = ”Trond”; a1.navn.equals(”Hallvard”) => false
Ansatt a1 = 16 String navn = int kontor = 0

Referanser til objekter
• Klassenavn kan/må brukes i deklarasjoner
– Ansatt a = new Ansatt(); // a kan ikke referere til noe annet enn Ansatt-instanser

• Variabler, parametre og felt kan referere til objekter
– void setNavn(Ansatt a, String s) { a.navn = s;}

• Metoder kan returnere objekter
– Ansatt lavesteKontornr(Ansatt a1, Ansatt a2) { return (a1.kontor < a2.kontor ? a1 : a2);}

• Flere variabler kan referere til samme objekt
– Ansatt a1 = new Ansatt(); a1.navn = ”Hallvard”; Ansatt a2 = a1; a2.navn = ”Trond”; a1.navn.equals(”Hallvard”) => false

Ansatt a1 = 17

String navn = ”Hallvard” int kontor = 0

Referanser til objekter
• Klassenavn kan/må brukes i deklarasjoner
– Ansatt a = new Ansatt(); // a kan ikke referere til noe annet enn Ansatt-instanser

• Variabler, parametre og felt kan referere til objekter
– void setNavn(Ansatt a, String s) { a.navn = s;}

• Metoder kan returnere objekter
– Ansatt lavesteKontornr(Ansatt a1, Ansatt a2) { return (a1.kontor < a2.kontor ? a1 : a2);}

• Flere variabler kan referere til samme objekt
– Ansatt a1 = new Ansatt(); a1.navn = ”Hallvard”; Ansatt a2 = a1; a2.navn = ”Trond”; a1.navn.equals(”Hallvard”) => false

Ansatt a1 = Ansatt a2 = 18

String navn = ”Hallvard” int kontor = 0

Referanser til objekter
• Klassenavn kan/må brukes i deklarasjoner
– Ansatt a = new Ansatt(); // a kan ikke referere til noe annet enn Ansatt-instanser

• Variabler, parametre og felt kan referere til objekter
– void setNavn(Ansatt a, String s) { a.navn = s;}

• Metoder kan returnere objekter
– Ansatt lavesteKontornr(Ansatt a1, Ansatt a2) { return (a1.kontor < a2.kontor ? a1 : a2);}

• Flere variabler kan referere til samme objekt
– Ansatt a1 = new Ansatt(); a1.navn = ”Hallvard”; Ansatt a2 = a1; a2.navn = ”Trond”; a1.navn.equals(”Hallvard”) => false

Ansatt a1 = Ansatt a2 = 19

String navn = ”Trond” int kontor = 0

Objektstrukturer
• Felt i objekter kan referere til andre objekter
– feltet må være deklarert til å referere til riktig klasse – feltet må settes til et spesifikt objekt

• Eksempel:
public class Ansatt { String navn; Ansatt venstreNabo, høyreNabo; } Ansatt a1 = new Ansatt(), a2 = new Ansatt(), a3 = new Ansatt(); a1.navn = ”jag”; a2.navn = ”hal”; a3.navn = ”krogstie”; a1.venstreNabo = a2; a2.høyreNabo = a1; a2.venstreNabo = a3; a3.høyreNabo = a2;

20

String navn = ”jag” Ansatt venstreNabo = Ansatt høyreNabo =

String navn = ”hal” Ansatt venstreNabo = Ansatt høyreNabo =

String navn = ”krogstie” Ansatt venstreNabo = Ansatt høyreNabo =

Objektstrukturer
• Objekter kan kombineres med tabeller
– felt i objekter kan deklareres og settes til tabeller – tabeller kan inneholde objekter

• Eksempel:
public class Ansatt { String navn; Ansatt[] naboer; } Ansatt a1 = new Ansatt(), a2 = new Ansatt(), a3 = new Ansatt(); a1.naboer = new Ansatt[]{a2}; a2.naboer = new Ansatt[]{a1, a3}; a3.naboer = new Ansatt[]{a2}; String navn = ”jag” Ansatt[] naboer = 21 String navn = ”hal” Ansatt[] naboer = String navn = ”krogstie” Ansatt[] naboer =

Objektstrukturer
• Navigering
– .- og []-notasjonene (og metodekall) kan brukes til navigering mellom objekter i en objektstruktur (og til tilordning med =)

• Gitt
String navn = ”jag” Ansatt venstreNabo = Ansatt høyreNabo =

Ansatt a1 =

, a2 =

, a3 =

String navn = ”hal” Ansatt venstreNabo = Ansatt høyreNabo =

String navn = ”krogstie” Ansatt venstreNabo = Ansatt høyreNabo =

– a1.venstreNabo.venstreNabo.navn = = ”krogstie”
22

Objektstrukturer
• Navigering
– .- og []-notasjonene (og metodekall) kan brukes til navigering mellom objekter i en objektstruktur (og til tilordning med =)

• Gitt
Ansatt a1 = , a2 = , a3 =

String navn = ”jag” Ansatt[] naboer =

String navn = ”hal” Ansatt[] naboer =

String navn = ”krogstie” Ansatt[] naboer =

– a3.naboer[0].naboer[0].navn == ”jag”
23

Hva skjer når en referanse er uinitialisert/tom?
• Referansen til ”ingenting” kalles null
– null er ikke et objekt i seg selv, men en verdi som representerer ”intet objekt” – teknisk sett kan alle (objekt)referanser være null (felt/attributter, variabler, returverdier og verdien av uttrykk)

• Hva kan en gjøre med null-verdier?
– kun testing av identitet (== og !=) og type (instanceof) gir mening – når en prøver å lese eller sette et attributt eller kalle en metode på null-referansen, så kræsjer programmet Ansatt a; // ikke initialisert med f.eks. new Ansatt()!!! a.navn = ”Hallvard” // tryner med NullPointerException!!!

• ”Å gjøre noe med null er tull”
24

Instansmetoder
• Metoder merket med static utføres kun i kontekst av de statiske variablene (som i Java-terminologi også kalles felt)
– statiske variabler er globale, som ”ses” av statiske metoder – ”arket” med globale variabler omslutter all kode

• Metoder uten static (i praksis det vi betrakter som vanlig metoder) kjører i kontekst av enkeltobjekter
– instanser kan ses på som små-ark (omtrent som kartotek- eller visittkort) – instansmetoder (metoder uten static) kjører innenfor arket – public class Ansatt { public String navn; public int kontor; public String getNavn() { return navn; } public void setNavn(String nyttNavn) { navn = nyttNavn; } }
25

Instansmetoder
• public class Ansatt { public String navn; public int kontor; public String getNavn() { return navn; } String navn = public void setNavn(String s) { int kontor = 0 navn = s; } } public class Hovedprogram { String[] args public static void main(String[] args) { Ansatt a = Ansatt a = new Ansatt(); a.setNavn(”hal”); // .-notasjonen og metodenavn if (a.getNavn() == ”hal”) { System.out.println(”Ja, det virker!”); } } } Arkmodellen må utvides ved at instansarket/kortet omslutter metodens ark

26

Instansmetoder
• public class Ansatt { public String navn; public int kontor; public String getNavn() { return navn; } String navn = public void setNavn(String s) { int kontor = 0 navn = s; } } public class Hovedprogram { public static void main(String[] args) { String[] args Ansatt a = new Ansatt(); Ansatt a = a.setNavn(”hal”); // .-notasjonen og metodenavn if (a.getNavn() == ”hal”) { System.out.println(”Ja, det virker!”); } } } Arkmodellen må utvides ved at instansarket/kortet omslutter metodens ark

27

Instansmetoder
• public class Ansatt { public String navn; public int kontor; String navn = ”hal” public String getNavn() { int kontor = 0 return navn; } String s = ”hal” public void setNavn(String s) { navn = s; } } public class Hovedprogram { String[] args public static void main(String[] args) { Ansatt a = Ansatt a = new Ansatt(); a.setNavn(”hal”); // .-notasjonen og metodenavn if (a.getNavn() == ”hal”) { System.out.println(”Ja, det virker!”); } } } Arkmodellen må utvides ved at instansarket/kortet omslutter metodens ark

28

Instansmetoder m/this-referanse
• public class Ansatt { public String navn; public int kontor; String navn = public String getNavn() { int kontor = 0 return navn; } this = public void setNavn(String s) { String s = ”hal” navn = s; } } public class Hovedprogram { String[] args public static void main(String[] args) { Ansatt a = Ansatt a = new Ansatt(); a.setNavn(”hal”); // .-notasjonen og metodenavn if (a.getNavn() == ”hal”) { System.out.println(”Ja, det virker!”); } } } Metodens ark har en spesiell referanse til instansen, i form at en konstant med navn this. Denne brukes for å nå objektet selv, samt felt med samme navn som variabler.

29

Instansmetoder m/this-referanse
• public class Ansatt { public String navn; public int kontor; String navn = ”hal” public String getNavn() { int kontor = 0 return navn; } this = public void setNavn(String s) { String s = ”hal” navn = s; } } public class Hovedprogram { String[] args public static void main(String[] args) { Ansatt a = Ansatt a = new Ansatt(); a.setNavn(”hal”); // .-notasjonen og metodenavn if (a.getNavn() == ”hal”) { System.out.println(”Ja, det virker!”); } } } Metodens ark har en spesiell referanse til instansen, i form at en konstant med navn this. Denne brukes for å nå objektet selv, samt felt med samme navn som variabler.

30

Instansmetoder m/this-referanse
• public class Ansatt { public String navn; public int kontor; String navn = ”hal” public String getNavn() { int kontor = 0 return navn; } public void setNavn(String s) { navn = s; } } public class Hovedprogram { String[] args public static void main(String[] args) { Ansatt a = Ansatt a = new Ansatt(); a.setNavn(”hal”); // .-notasjonen og metodenavn if (a.getNavn() == ”hal”) { System.out.println(”Ja, det virker!”); } } } Metodens ark har en spesiell referanse til instansen, i form at en konstant med navn this. Denne brukes for å nå objektet selv, samt felt med samme navn som variabler.

31

statiske vs. ikke-statiske metoder
• Metodekall
– – Statiske metoder kalles ved navn, evt. med <klassenavn>.<metodenavn> Ikke-statiske metoder (heretter kun kalt metoder) kalles med <objektuttrykk>.<metodenavn> metoden har en implisitt this-referanse this-referansen refererer til verdien til <objektuttrykk>

Metoder utføres i kontekst av et objekt
– –

Navn brukt som referanser i uttrykk inni metoder refererer enten til variabler i metoden eller felt i objektet
– – Referanse til felt: String getNavn() { return navn;} Referanse til både felt og variabel: void setNavn(String s) { navn = s;}

• this kan brukes som referanse til objektet selv i uttrykk, f.eks. for å gjøre uttrykket entydig eller bruke objektet som parameter
– void setNavn(String navn) { this.navn = navn;}

32

Eksempler på statiske vs. ikke-statiske metoder
• Typiske statiske metoder
– – – Metoder som ikke er knyttet til noen instans // lage spesiell instans, bruker ikke eksisterende instans static Ansatt createAnsatt() { ... } Metoder som behandler to eller flere instanser likt kan godt være statiske // sammenligne to objekter static Ansatt compareAnsatt(Ansatt a1, Ansatt a2) { ... } Hjelpemetoder som behandler ikke-objekt-verdier, som tabeller og tall // sorter tabell static void sort(Ansatt[] ansatte) { ... } metoder som kun gir mening med et objekt av en bestemt type // converter objekt til HTML, for visning i web-side String toHTML() { ... } metoder som returnerer verdier som er direkte avledet av felt i objektet // returner etasjen til en ansatt int etasje() { return kontor / 100;} metoder som endrer på ikke-statiske felt i et objekt // endre ansattes fornavn void setFornavn() { ... }

Typiske ikke-statiske metoder
– – –


33

Det er statiske metoder som er unntaket!

Initialisering av objekter med konstruktører
• De fleste objekter må initialiseres før de får en meningsfylt innhold/tilstand
– Ansatt a = new Ansatt(); a.navn = ...

En konstruktør (eng: constructor) er en spesielle metode som brukes til nødvendig initialisering ifm. bruk av new-operatoren
– public class Ansatt { String navn; public Ansatt(String navn) { this.navn = navn; // en konstruktør har ingen eksplisitt retur-verdi } } Ansatt a = new Ansatt(”Hallvard”);

• •

Konstruktøren deklareres som en metode uten returtype og med klassens navn evt. med klassen som returtype og uten navn Konstruktøren vs. new-operatoren
– – konstruktøren kalles automatisk av new-operatoren, etter at objektet er laget new-operatoren tar de samme parametrene som konstruktøren

34

Litt om objekter vs. ikke-objekter
• Sannhetsverdier, tall og tegn er ikke objekter i noen forstand (siden skal vi se objektvarianter av disse typene)
– kan ikke bruke 1.pluss(2) – for hver ikke-objekttype finnes en klasse med hjelpemetoder for denne typen, f.eks. int/Integer, double/Double, char/Character

• Integer (og tilsvarende for Double)
– Integer.toString(int) konverterer int til String – Integer.valueOf(String) konverterer String som int

• Character
– Character.isUpperCase(char) og Character.isLowerCase(char) sjekker om en bokstav er stor (upper) eller liten (lower) – Character.toUpperCase(char) og Character.toLowerCase(char) konverterer en liten bokstav til en stor og omvendt

• Tabeller
– tabeller ligner på objekter, fordi de har såkalt identitet, kan endres på og deles – tabeller har ikke metoder, kun length-attributtet
35

Litt om String og objekter
• String er en klasse
– String-klassen har noen nyttige statiske konverteringsmetoder

String-instanser er objekter og har en rekke nyttige metoder (merk at String-konstanter er String-uttrykk)
– indexOf og lastIndexOf – finner hvor en String eller char finnes i String’en: ”Hallvard”.indexOf(”ll”) => 2 – startsWith(String) og endsWith(String) for å test på prefiks og suffiks: ”Hallvard”.startsWith(”Hall”) => true – substring – lager en ny String som består av en bit av String’en: ”Hallvard”.substring(2, 4) => ”ll”

• String-klassen ligner på ikke-objekter på to måter
– String-objekter håndteres spesielt av +-operatoren: ”Ha” + ”ll” + ”vard” => ”Hallvard” – String-objekter kan ikke endres
• det finnes ingen måter/metoder som endrer på eksisterende String-objekter • String-objekter kan deles uten at endringer et sted synes et annet 36

Verdier og objekter
referanse (pil) boolean/ int o.l. String tabell objekt klasse
37

kan endres har metoder

pga. impl.

avhengig av impl. refereres bare med navn

Objekter, tekst og utskrift: toString()-metoden
• Noen operasjoner krever at objektreferanser gjøres om til tekst (String)
– + operatoren, når venstre side er en tekst, f.eks. ”Ansatt: ” + ansatt – Metoder som println vil gjøre om objektreferanser til tekst

• Konvertering til String
– null-referansen blir til ”null” – objekter konverteres ved å kalle String.valueOf(obj), som i sin tur kaller toString()-metoden, deklarert som public String toString() – objekter uten en slik egendefinert metode blir skrevet ut som <klassenavn>@<hexkode>

38

toString()-metoden
• toString()-metoden brukes ved konvertering av objekter til tekst (String), f.eks. ved utskrift med println og print • Ved å definere toString()-metoden i egne klasser, endrer en hvordan egne objekter gjøres om til tekst • Den returnerte verdien (av typen String) bør være
– knapp, dvs. ikke ta for mye plass – informativ nok til å gjenkjenne objektet – vise egenskaper som er essensielle ved feilfinning

• Vår toString()-metode bruker en vanlig konvensjon
– ’[’<klassenavn> <essensielle attributter>’]’
39