INF 101-10. mars 2003 Mer om klasser og objekter Ole Christian Lingjærde Gruppen for bioinformatikk Institutt for informatikk Universitetet i Oslo Java 12 To måter å programmere på Statisk programmering: Har vært fokus i kurset fram til nå Vi lager ikke objekter av klassene Alle variable og metoder er deklarert som static Programmering med objekter: Er fokus for resten av kurset Vi lager objekter av klassene (noen eller alle) Variable og metoder er vanligvis ikke deklarert som static Dagens forelesning: Forskjellen mellom statiske og ikke-statiske variable og metoder Hvorfor programmere med objekter Flere eksempler på programmering med objekter Ole Chr. Lingjærde Institutt for informatikk 10. mars 2003 2 Statisk programmering Programmering med objekter class VolumBeregning { static int maxantall = 10; static double finnvolum(double radius) { static int finnsum(int k) { Alle variable er deklarert som static Alle metoder er deklarert som static class StudentRegister { void init() { String finnnavn() { Variable er ikke deklarert som static (vanligvis) Metoder er ikke deklarert som static (vanligvis) Ole Chr. Lingjærde Institutt for informatikk 10. mars 2003 3 Ole Chr. Lingjærde Institutt for informatikk 10. mars 2003 4
Å lage objekter Pekere (referanser) Objekter lages med new For hvert nytt objekt får vi et fullt sett med nye objektvariable: new Student(); new Student(); navn: fnr : navn: fnr : Når vi lager et objekt med new får vi returnert en peker til objektet: Student stud = new Student(); Variable og metoder i objektet får vi tak i gjennom "prikk-notasjon": stud.navn = "Cathrine"; String s = stud.finnnavn(); 1) Deklarer en Student-peker stud 2) Lag et objekt av klassen Student 3) Sett stud til å peke på objektet new Student(); En peker trenger ikke å peke på samme objekt hele tiden: navn: fnr : Student stud = new Student(); stud = new Student(); // Nå peker stud på det nye objektet // Det første objektet er det ikke mulig å få fatt i lenger Ole Chr. Lingjærde Institutt for informatikk 10. mars 2003 5 Ole Chr. Lingjærde Institutt for informatikk 10. mars 2003 6 Eksempel Objektvariablenes levetid class MittProgram { Student stud1, stud2; stud1 = new Student(); stud1.navn = Kari Olsen ; stud1.fnr = 14058767781 ; stud2 = new Student(); stud2.navn = Jens Fredriksen ; stud2.fnr = 05055023456 ; Disse variablene blir deklarert når vi lager et objekt av klassen ved å skrive new Student(), og de lever så lenge objektet lever. System.out.println(stud1.navn + har fnr + stud1.fnr); System.out.println(stud2.navn + har fnr + stud2.fnr); > javac MittProgram.java > java MittProgram Kari Olsen har fnr 14058767781 Jens Fredriksen har fnr 05055023456 Ole Chr. Lingjærde Institutt for informatikk 10. mars 2003 7 Objektvariablene blir til når objektet blir til (med new) Objektvariablene lever så lenge objektet finnes Ole Chr. Lingjærde Institutt for informatikk 10. mars 2003 8
Hvorfor programmere med objekter? Med objekter kan vi ofte organisere våre data bedre. Eksempel: String [] navn = new String[100]; String [] fnr = new String[100]; int [] tlfnr = new int[100]; Informasjonen knyttet til en bestemt person er splittet opp i tre arrayer. Hvorfor programmere med objekter? Med objekter kan vi samle data og operasjoner på dem. data om studenter data om ansatte data om kurs student-metoder ansatt-metoder kurs-metoder Her ligger alle data og alle metoder samlet ett sted int tlfnr; Person [] personreg = new Person[100]; Informasjonen knyttet til en bestemt person er samlet i et objekt. Bedre organisering særlig når det er mye data å holde orden på. Ole Chr. Lingjærde Institutt for informatikk 10. mars 2003 9 data om studenter student-metoder class Ansatt { data om ansatte ansatt-metoder class Kurs { data om kurs kurs-metoder Metoder og data som hører sammen er samlet. Lett å se hvilke metoder som jobber på hvilke data (modularisering av koden). Lett å kopiere alt som har med personer å gjøre (data+metoder) til andre programmer (gjenbruk). Ole Chr. Lingjærde Institutt for informatikk 10. mars 2003 10 Det er forskjell på pekerlikhet og innholdslikhet: class Likhet { Student stud1 = new Student(); stud1.navn = "Petter"; stud1.fnr = "01018926324"; Student stud2 = new Student(); stud2.navn = "Petter"; stud2.fnr = "01018926324"; if (stud1 = = stud2) System.out.println("Samme objekt"); To typer likhet if ((stud1.navn = = stud2.navn) && (stud1.fnr = = stud2.fnr)) System.out.println("Samme innhold"); Ole Chr. Lingjærde Institutt for informatikk 10. mars 2003 11 En tekststreng er egentlig et objekt: class TekstStrenger { String s1 = "Hei på deg"; String s2 = new String("Hei på deg"); Eksempel: String Både pekerlikhet og innholdslikhet er ferdig implementert for String: class TekstStrenger2 { String s1 = "Hei på deg"; String s2 = "Hei på" + "deg" System.out.println(s1); System.out.println(s2); if (s1 == s2) System.out.println("Referanselikhet"); if (s1.equals(s2)) System.out.println("Innholdslikhet"); Ole Chr. Lingjærde Institutt for informatikk 10. mars 2003 12
Klassevariable (statiske variable) Klassevariablenes levetid Statiske variable deklareres kun en gang, uansett antall objekter av klassen: static int maxalder=100; int alder=0; String navn=""; maxalder: 100 når klassen refereres første gang new Person(); new Person(); new Person(); alder: 0 navn : "" alder: 0 navn : "" alder: 0 navn : "" static int maxalder=100; int alder; void metode() { Denne blir deklarert første gang klassen Person blir referert til under kjøringen av programmet. Variabelen lever helt til programmet avsluttes. Første gang klassen Person blir referert til = første gang en slik instruksjon utføres:. new Person().. Person.maxAlder.. Person.metode().. Ole Chr. Lingjærde Institutt for informatikk 10. mars 2003 13 Ole Chr. Lingjærde Institutt for informatikk 10. mars 2003 14 main og statiske variable To måter å bruke en klasse på Fila Utskrift.java: class Utskrift { double e = 2.72; System.out.println(pi); Dette går bra siden den statiske variabelen pi blir deklarert når main-metoden kalles av Java (dvs ved programstart). Det ville ikke gå bra å bruke variabelen e, siden det er ikke laget noe objekt av klassen. Ole Chr. Lingjærde Institutt for informatikk 10. mars 2003 15 Uten å lage objekt av klassen: Minklasse.a = 14; Minklasse.x = 33.63; Disse gir kompileringsfeil: Minklasse.b = Minklasse.y = class MinKlasse { static int a; static double x; int b; double y; Lage objekt av klassen: Minklasse m = new MinKlasse(); m.a = 14; m.x = 33.63; m.b = 46; m.y = 63.1; Ole Chr. Lingjærde Institutt for informatikk 10. mars 2003 16
Oppsummering: Klassevariable og objektvariable class SirkelEksempel { System.out.println("Pi = " + Sirkel.pi); Sirkel s = new Sirkel(); System.out.println("Radius = " + s.radius); double radius = 2.0; Objektvariable er bare definert i objekter av klassen, og hvert objekt har sitt eget sett med objektvariable. Klassevariable er felles for alle objektene av klassen, og slike variable er også definert selv om det ikke er laget noen objekter av klassen. Ole Chr. Lingjærde Institutt for informatikk 10. mars 2003 17 Hvilke av setningene i main-metoden er lovlige? class Oppgave { static int [] x = {2, 6, 9; int [] y = {4, 6, 8; Oppgave System.out.println(x[2]); System.out.println(x[2] + y[2]); Bil.antallBiler = 3; Bil.eier = "Marit"; Bil b = new Bil(); b.antallbiler = 6; b.eier = Arne"; class Bil { static int antallbiler = 0; String eier, regnr; Ole Chr. Lingjærde Institutt for informatikk 10. mars 2003 18 Klassemetoder og objektmetoder Hvem ser hvem i en klasse Klassemetoder (static) Definert selv om det ikke er laget noen objekter av klassen Kan ses av alle objekter av klassen Kan brukes av andre gjennom dot-notasjon: <klassenavn>.metode() Har ikke tilgang til objektvariable eller objektmetoder Objektmetoder (ikke static) Bare definert i objekter av klassen Kan ses av objektet som metoden befinner seg i Kan brukes av andre gjennom dot-notasjon: <peker>.metode() Har tilgang til alle variable (både klassevariable og objektvariable) og alle metoder (både klassemetoder og objektmetoder) Klassemetoder kan benytte Klassevariable kan benytte kan benytte Objektmetoder kan benytte Objektvariable Ole Chr. Lingjærde Institutt for informatikk 10. mars 2003 19 Ole Chr. Lingjærde Institutt for informatikk 10. mars 2003 20
class Volum { System.out.println(Matte1.pi); System.out.println(Matte1.finnVolum(2.5)); Matte2 mat = new Matte2(); System.out.println(mat.pi); System.out.println(mat.finnVolum(2.5)); class Matte1 { static double finnvolum (double radius) { return 3 * pi * Math.pow(radius, 3) / 4; class Matte2 { double pi = 3.14; double finnvolum (double radius) { return 3 * pi * Math.pow(radius, 3) / 4; Statisk bruk av annen klasse Bruk objekt av annen klasse I denne klassen er alle variable og metoder statiske I denne klassen er alle variable og metoder ikke-statiske Hvorfor er pi klassevariabel her? class TestSirkel { Sirkel s = new Sirkel(); System.out.print("Arealet til en sirkel med radius "); System.out.println(s.radius + " er " + s.finnareal()); double radius = 1.0; double finnareal() { return pi * radius * radius; Ole Chr. Lingjærde Institutt for informatikk 10. mars 2003 22 class StudentRegister { Student s1, s2; s1 = new Student(); s1.init("torjus", "S25332"); s2 = new Student(); s2.init("avril", "S36336"); s1.skrivut(); s2.skrivut(); static static String studid; static void init(string n, String s) { navn = n; studid = s; static void skrivut() { System.out.println("Navn: " + navn); System.out.println("StudId: " + studid); Oppgave: Ole lærer å programmere og har laget programmet til venstre. Hva skriver programmet ut på skjermen? Lokale variable i metoder (også parametre) kan ha samme variabelnavn som objektvariable deklarert i klassen. Det er da de lokale variablene og parametrene som har "fortrinn", dvs objektvariablene med samme navn "overskygges". Vi kan likevel få tilgang til objektvariablene ved å benytte en peker til objektet og prikk-notasjon. Ethvert objekt inneholder en slik peker til seg selv: this String navn = Andre Bjerke ; void byttnavn (String navn) { this.navn = navn; parameteren navn objektvariabelen navn this Ole Chr. Lingjærde Institutt for informatikk 10. mars 2003 24
Initialisering av variable i et objekt Finn- og sett-metoder Anta at programmet vårt inneholder denne klassen: Når vi har laget et objekt (med new) ønsker vi normalt å gi variablene i objektet fornuftige verdier med en gang. Noen muligheter: Sett verdiene til objektvariablene direkte med prikk-notasjon: Person p = new Person(); p.navn = Petter ; p.fnr = 15108559879 ; Lag en init-metode i klassen: Person p = new Person(); p.init( Petter, 15108559879 ); Benytt en konstruktør: Person p = new Person( Petter, 15108535738 ); Ole Chr. Lingjærde Institutt for informatikk 10. mars 2003 25 Når man skal lage "virkelige" programmer er det vanlig å Deklarere alle objektvariable som private Bruke finn- og sett-metoder for å endre på objektvariable class Eksempel { Student stud = new Student(); stud.settnavn("petter"); System.out.println(stud.finnNavn()) private private void settnavn(string navn) {this.navn = navn; String finnnavn() {return this.navn; NB: dere har ikke fått denne foilen Ole Chr. Lingjærde Institutt for informatikk 10. mars 2003 26 Konstruktører Eksempel En konstruktør er en spesiell type objektmetode som du kan bruke for å sikre at objektet starter sitt liv med fornuftige verdier i objektvariablene. Konstruktører har alltid samme navn som klassen de ligger i utføres automatisk når et objekt opprettes med new har ingen returverdi, men skal ikke ha void foran seg overlastes ofte, dvs det er ofte flere konstruktører i en og samme klasse, hvor konstruktørene skiller seg fra hverandre ved antall parametre og/eller typen på parametrene. Ole Chr. Lingjærde Institutt for informatikk 10. mars 2003 27 class TestSirkel { Sirkel s1 = new Sirkel(); System.out.println("Radius: " + s1.radius); Sirkel s2 = new Sirkel(5.0); System.out.println("Radius: " + s2.radius); double radius; Sirkel () { radius = 1.0; Sirkel (double r) { radius = r; Konstruktør 1 Konstruktør 2 Ole Chr. Lingjærde Institutt for informatikk 10. mars 2003 28
Når det ikke er noen konstruktør Oppgave: virker dette? Når en klasse ikke inneholder noen konstruktør, vil Java selv føye på en "tom konstruktør" uten parametre når programmet kompileres. Dermed er følgende to klassedeklarasjoner ekvivalente: double radius; Sirkel () { double radius; Lar dette programme seg kompilere og kjøre? class Oppgave1 { Bil b = new Bil(); class Bil { String regnr; Merk: dersom klassen inneholder en eller flere konstruktører, vil Java ikke føye på en "tom konstruktør" uten parametre. Bil (String regnr) { this.regnr = regnr; Ole Chr. Lingjærde Institutt for informatikk 10. mars 2003 29 Ole Chr. Lingjærde Institutt for informatikk 10. mars 2003 30 Oppgave Lag et program for et personregister. Programmet skal: først be om og lese inn opplysninger om 5 personer: navn og favorittfarge deretter skrive ut alle opplysningene til fil Tid til rådighet: 5 min! Skriv programmet Ole Chr. Lingjærde Institutt for informatikk 10. mars 2003 31 Ole Chr. Lingjærde Institutt for informatikk 10. mars 2003 32
Oppgave: hva gjøres når? I hvilken rekkefølge skjer de ulike tingene når dette programmet kjøres? class Oppgave2 { // (1) // (2) Oppgave2 op = new Oppgave2("Petter"); // (3) op.skrivnavn(); // (4) Oppgave2 (String navn) { this.navn = navn; // (5) void skrivnavn() { System.out.println("Navnet er : " + navn); // (6) Ole Chr. Lingjærde Institutt for informatikk 10. mars 2003 33 Ole Chr. Lingjærde Institutt for informatikk 10. mars 2003 34 Oppgave: hva skrives ut? To avsluttende spørsmål class Oppgave3 { static String s1 = v('a'); String s2 = v('b'); String s3 = v('c'); Oppgave3 op = new Oppgave3(); op.skrivut(); Oppgave3 () { s2 = v('d'); static String v (char c) { System.out.println(c); return "" + c; void skrivut() { System.out.println('e'); Ole Chr. Lingjærde Institutt for informatikk 10. mars 2003 35 Hvor mange Person-objekter lages her: Person [] allepersonene = new Person[50]; Anta at vi har laget klassen Person: String fødselsnummer; String adresse; Hvordan ville du sjekke om to Person-pekere p1 og p2 faktisk representerer samme person? Ole Chr. Lingjærde Institutt for informatikk 10. mars 2003 36