Data. Dette refereres til som objektets tilstander. Funksjonalitet. Dette refereres til som objektets metoder.

Like dokumenter
public static <returtype> navn_til_prosedyre(<parameter liste>) { // implementasjon av prosedyren

public static <returtype> navn_til_prosedyre(<parameter liste>) { // implementasjon av prosedyren

OPPGAVE 1 OBLIGATORISKE OPPGAVER (OBLIG 1) (1) Uten å selv implementere og kjøre koden under, hva skriver koden ut til konsollen?

OPPGAVESETT 7 OBJEKTER OG REFERANSER

Introduksjon til objektorientert. programmering. Hva skjedde ~1967? Lokale (og globale) helter. Grunnkurs i objektorientert.

UNIVERSITETET I OSLO

Objekter og referanser

UNIVERSITETET I OSLO

Løsningsforslag ukeoppg. 6: 28. sep - 4. okt (INF Høst 2011)

Forkurs INF1010. Dag 1. Andreas Færøvig Olsen Tuva Kristine Thoresen

UNIVERSITETET I OSLO

programeksempel Et større En større problemstilling Plan for forelesingen Problemstillingen (en tekstfil) inneholdt ordet "TGA"

LC191D Videregående programmering Høgskolen i Sør-Trøndelag, Avdeling for informatikk og e-læring. Else Lervik, januar 2012.

UNIVERSITETET I OSLO

INF1010 våren 2008 Uke 4, 22. januar Arv og subklasser

Fra Python til Java. En introduksjon til programmeringsspråkenes verden. Dag Langmyhr

INF1000: Forelesning 7

INF1000: Forelesning 7. Konstruktører Static

IN1010. Fra Python til Java. En introduksjon til programmeringsspråkenes verden Dag Langmyhr

Innhold uke 4. INF 1000 høsten 2011 Uke 4: 13. september. Deklarasjon av peker og opprettelse av arrayobjektet. Representasjon av array i Java

INF1000: noen avsluttende ord

UNIVERSITETET I OSLO

Introduksjon til objektorientert programmering

Hva er verdien til variabelen j etter at følgende kode er utført? int i, j; i = 5; j = 10; while ( i < j ) { i = i + 2; j = j - 1; }

UNIVERSITETET I OSLO

Etter uke 6 skal du. Introduksjon til objektorientert programmering. Hva skjedde ~1967? INF1001. Grunnkurs i objektorientert programmering

Konstruktører. Bruk av konstruktører når vi opererer med "enkle" klasser er ganske ukomplisert. Når vi skriver. skjer følgende:

Forkurs INF1010. Dag 2. Andreas Færøvig Olsen Gard Inge Rosvold Institutt for Informatikk, 14.

Klasser, objekter, pekere og UML. INF gruppe 13

Forkurs INF1010. Dag 2. Andreas Færøvig Olsen Tuva Kristine Thoresen

Innhold uke 7. Objektorientert programmering i Python: Introduksjon. Lite tilbakeblikk: Programflyt og skop. Lite tilbakeblikk: Funksjoner er uttrykk

UNIVERSITETET I OSLO

IN1010. Fra Python til Java. En introduksjon til programmeringsspråkenes verden Dag Langmyhr

UNIVERSITETET I OSLO

Introduksjon til programmering og programmeringsspråk

Velkommen til. INF våren 2016

Endret litt som ukeoppgave i INF1010 våren 2004

Tilstandsmaskiner med UML og Java

UNIVERSITETET I OSLO

class Book { String title; } class Dictionary extends Book { int wordcount; } class CartoonAlbum extends Book { int stripcount; }

2 Om statiske variable/konstanter og statiske metoder.

INF1000 EKSTRATILBUD. Stoff fra uke 1-5 (6) 3. oktober 2012 Siri Moe Jensen

Arv. Book book1 = new Book(); book1. title = "Sofies verden" class Book { String title; } class Dictiona ry extends Book {

TDT4100 Objektorientert programmering

Feilmeldinger, brukerinput og kontrollflyt

INF våren 2017

Fra problem til program

Repitisjonskurs. Arv, Subklasser og Grensesnitt

Hvorfor objektorientert programmering? Objektorientert programmering i Python: Introduksjon. Læringsmål uke 7. Undervisning og pensum IN1000

IN våren 2019 Onsdag 16. januar

IN våren 2018 Tirsdag 16. januar

Ansvarsdrevet OO: CRC og UML Sekvensdiagrammer

Hvorfor objektorientert programmering?

UNIVERSITETET I OSLO

Programmering i C++ Løsningsforslag Eksamen høsten 2005

Hva er en metode. Hva skjer når vi kaller en metode

Spesifikasjon av Lag emne

Introduksjon til programmering og programmeringsspråk. Henrik Lieng Høgskolen i Oslo og Akershus

Eksekveringsrekkefølgen (del 1) Oppgave 1. Eksekveringsrekkefølgen (del 2) Kommentar til oppgave 1. } // class Bolighus

Læringsmål uke 7. Objektorientert programmering i Python: Introduksjon. Innhold uke 7. Lite tilbakeblikk: Programflyt og skop

INF1010 våren januar. Objektorientering i Java

Dagens tema Kapittel 8: Objekter og klasser

UNIVERSITETET I OSLO

INF1010 våren Arv og subklasser del 1

Oversikt. INF1000 Uke 1 time 2. Repetisjon - Introduksjon. Repetisjon - Program

INF1000 Prøveeksamen Oppgave 7 og 9

Etter uke 9 skal du. Introduksjon til objektorientert programmering. Innhold. Klasser som abstraksjoner

Kapittel 8: Programutvikling

EKSAMEN 6108/6108N PROGRAMMERING I JAVA Alt trykt og skriftlig materiale.

Seminaroppgaver IN1010, uke 2

INF1000 (Uke 15) Eksamen V 04

INF1000 (Uke 15) Eksamen V 04

UNIVERSITETET I OSLO

Oblig 4Hybelhus litt mer tips enn i oppgaven

Oversikt. INF1000 Uke 2. Repetisjon - Program. Repetisjon - Introduksjon

INF1000: noen avsluttende ord

Jentetreff INF1000 Debugging i Java

UNIVERSITETET I OSLO

Kort om meg. INF1000 Uke 2. Oversikt. Repetisjon - Introduksjon

INF Uke 10. Ukesoppgaver oktober 2012

Antall sider (inkl. forsiden): 7. Alle trykte og håndskrevne

INF1000 Eksamen 2014 (modifisert)

Objektorientert Programmering Ekstraordinær eksamen 2014

INF1010 UML. Marit Nybakken 26. januar 2004

IN Notat om I/O i Java

Eksamen i emnet INF100 Grunnkurs i programmering (Programmering I) og i emnet INF100-F Objektorientert programmering i Java I Løsningsforslag

Oppsummering. Kort gjennomgang av klasser etc ved å løse halvparten av eksamen Klasser. Datastrukturer. Interface Subklasser Klasseparametre

Eksamen. Objektorientert Programmering IGR 1372

INF Obligatorisk innlevering 5

UNIVERSITETET I OSLO

EKSAMENSFORSIDE SKRIFTLIG EKSAMEN

UNIVERSITETET I OSLO

Eksamen Objektorientert Programmering 2011

Fra krav til objektdesign

Objektorientert programmering i Python

Gjennomgang av eksamen H99

2 Om statiske variable/konstanter og statiske metoder.

OO-eksempel. Modellen ser slik ut: Studenter + antstudenter : int = 0

IN1010 våren januar. Objektorientering i Java

TDT4100 Objektorientert programmering

Transkript:

Objekter og klasser Introduksjon til objekter I prosedyre-basert programmering, deles programmet inn i prosedyrer. Slik oppdeling gjøres for å håndtere kompleksitet. Objekt-orientert programmering er en annen type programmeringsstil med samme mål: håndtering av kompleksitet. I objekt-orientert programmering deles programmet opp i objekter. Følgende aspekter er relatert til hvert objekt: Data. Dette refereres til som objektets tilstander. Funksjonalitet. Dette refereres til som objektets metoder. Det vil si, hvert objekt holder på en eller flere interne tilstander når programmet kjører. I tillegg, tilbyr objektet ulike funksjonaliteter, ofte basert på nåværende tilstand til objektet. Programmerer kan bruke objektets funksjonaliteter via objektets sine metoder. Eksempel Vi skal implementere et informasjonssystem som skal inneholde informasjon om alle studenter og ansatte ved norske universiteter og høgskoler. I objekt-orientert programmering, modellerer vi objekter som representerer programmet. I dette eksempelet, kan vi tenke oss følgende objekter: Student. Et objekt som representerer en student. Objektet skal inneholde data som navn, studentnummer, og fødselsår. Foreleser. Et objekt som representerer en foreleser. Objektet skal inneholde data som navn, kontornummer, og lønnstrinn. Kurs. Et objekt som representerer et kurs, som DAPE1400 Programmering. Objektet skal inneholde data som en gruppe med studenter og forelesere, tittel, og id. I tillegg, skal objektet tilby funksjonaliteten å printe ut alle studenter som tar kurset til konsollen. I tillegg, kan vi se for oss objekter som avdeling, klasse (eks. dataingeniør), fakultet, og universitet. Som vi ser, desto mer komplekst systemet skal være, desto flere objekter trenger vi. Vi får også flere avhengigheter mellom objekter. Eksempel på avhengighet: et kurs inneholder en gruppe med studenter. For å modellere kurs, trenger vi dermed å modellere konseptet "student". Vi sier dermed at kurs er avhengig av student. Objekter i programmering Et objekt fungerer som en statisk datacontainer, slik som tabeller. Et objekt kan imidlertid støtte variabler av forskjellige typer. For å muliggjøre dette, håndteres objekter av kompilatoren. Kompilatoren konverterer objekter til variabler og håndterer manuelt muligheten for aksessering av individuelle variabler. Dog, i Java håndteres objekter direkte av Javas virtuelle maskin (som er programmert i C). De fleste språk støtter muligheten for å definere objekter. Eksempel: Selv om C ikke er et objektorientert språk, støtter C objekter. Det som gjør C et ikke-objekt-orientert språk er at C ikke tilbyr den funksjonalitet som forventes av et objekt som er programmert etter stilen objekt-orientert programmering. Mer spesifikt, separerer C objektet og funksjonaliteten relatert til objektet. Funksjonalitet relatert til objekter implementeres med prosedyrer og ikke med metoder.

Objekt-orienterte språk, som Java og C++, støtter all funksjonalitet som er forventet for denne stilen. Mer spesifikt tilbyr Java muligheten å relatere funksjonalitet, via metoder, direkte til objektet. Vi programmerer ikke lengre med tradisjonelle prosedyrer, vi programmerer i metoder. Den mest populære måten å støtte objekt-orientert programmering på er via klasser. Dette er fremgangsmåten som tilbys av både Java, C++, og Python. Klasser beskriver objekter: de definerer objektets tilstander og metoder. Merk at alternativer til klasse-orientert programmering finnes, men er mindre populære. Det primære alternativet er prototype-basert programmering. Klasser i Java: syntaks For å definere en ny klasse i Java, så må en ny fil opprettes. Filnavnet må være det samme som navnet til klassen. For eksempel, hvis navnet til klassen er MinKlasse, så må filnavnet være MinKlasse.java Klasser defineres i Java ved følgende syntaks: public class MinKlasse { // objektets tilstander // denne delen refereres ofte til som klassens datafelt private int a; private double b; // merk at vi ikke bruker static her // Klassens konstruktør. Denne kalles når objektet opprettes // merk at vi ikke returnerer noe i denne "prosedyren" public MinKlasse() { a = 10; // vi har tilgang til objektets tilstander b = 10.0; // Konstruktører kan ta parametere som vanlige prosedyrer public MinKlasse(int verdi1, double verdi2) { a = verdi1; b = verdi2; // Funksjonalitet angis via metoder // merk, vi trenger ikke static her og vi har // tilgang til objektets tilstander public void printinfo() { System.out.println("Int verdi: "+a +", double verdi:"+b); Klasser definerer objekter. For eksempel, hvis vi ønsker objekter av typen Student, så må vi først opprette en klasse Student. Deretter kan vi opprette konkrete objekter av typen Student (med et konkret navn, studentnummer osv.). Følgende kode oppretter objekter av typen MinKlasse. Koden er angitt i main-prosedyren.

// Opprett et objekt med new-operatoren MinKlasse obj1 = new MinKlasse(); // Den første konstruktøren angitt i klassen blir kalt. // Verdiene til variablene (a og b) blir dermed 10: obj1.printinfo(); // metoder (funksjonalitet) som tilbys av objektet aksesseres // med punktum etter objekt-variabelen, som vist over. // Vi kan også bruke den andre konstruktøren: MinKlasse obj2 = new MinKlasse(5, 5.0); // skriver ut tilstandene til obj2, som er 5: obj2.printinfo(); Eksempel Vi ønsker å modellere konseptet dato i programmet vårt. En dato inneholder dataene år, måned, og dag. Noen datoer har også spesielle navn, som julaften (24. desember). Se Date.java for dette eksempelet. Hvordan klasser kompileres og brukes demonstreres videre i oppgavesett 6. Beskrivelse av klasser: UML klassediagram For å modellere og beskrive klasser, bruker man språket UML (unified modelling language). Vi bruker UML klassediagrammer for å beskrive klasser og relasjonen mellom klasser i dette faget. Tilstander - betyr privat aksessering + betyr public aksessering Funksjonalitet Pil (->) angir en "has-a" relasjon: En student går på et (og bare et) universitet, mens et universitet inneholder mange (0...*) studenter. Merk: hensikten med UML er å kommunisere ideer, ikke å beskrive systemet i sin helhet. Dette betyr at UML klassediagrammer ofte ikke beskriver alle tilstander og metoder til klassen, men heller et minimum for å kommunisere hensikten med klassen og dens primære oppførsel. Det er ikke hensiktsmessig å beskrive klasser fullt ut fordi det blir for mye vedlikeholdsarbeid ettersom klassen kontinuerlig endres på. I praksis, blir dermed UML mest brukt for å diskutere ideer, spesielt i starten

av et prosjekt, men blir ikke brukt for å dokumentere allerede implementerte klasser. Det finnes bedre dokumenteringsverktøy for dette, noe vi kommer tilbake til i faget Programutvikling. Diskusjon Hvordan identifisere objekter og metoder? Modellering av klasser oppstår ofte direkte fra domenet til problemet ditt. For eksempel, så vi at objekter kan relativt enkelt modelleres i universitets-eksempelet med bakgrunn av vår forståelse av domenet (hva et universitet er). Modellering er et håndverk og ikke en eksakt vitenskap. Vanligvis, oppretter man klasser som naturlig beskriver domenet for deretter å iterativt modifisere disse inntil vi har en robust struktur med objekter og klasser som grupperer tilstander og funksjonalitet på en naturlig måte. Et populær fremgangsmåte er å bryte ned problemet i korte beskrivelser (use case). I disse beskrivelsene, vil subjektiv relatere til objekter, mens verb relaterer til metoder. Eksempel: "htmlviewer requests html document from urlto be parsed by htmlparser." Objekter: htmlviewer, html document, url, htmlparser Metoder: request (htmlviewer), parse (htmlparser). Merk at mer avanserte teknikker for modellering av objekter og metoder blir presentert i faget Programutvikling. Hvilke fordeler tilbyr objekt-orientert programmering oss? Objekt-orientert programmering fremmer bruk av følgende aspekter: Modularitet Gjenbruk av kode Innkapsling av data (information hiding) (arv og polymorfisme) introdusert senere i faget Merk at prosedyre-basert programmering fremmer alle disse punktene også (utenom arv). Modularitet: bryt ned store problemer i mindre biter (klasser). Utvikling, testing, og vedlikehold kan dermed gjøres individuelt for hver bit, noe som gjør større programmer håndterbare. Gjenbruk av kode: Et program representerer ofte generelle objekter, som kan brukes i andre programmer. For eksempel, kan vår universitetsapp, med ansatte og studenter, videreføres til andre prosjekter der man trenger representasjoner av ansatte og/eller studenter (for eksempel, en app for en studentklubb). Innkapsling av data (information hiding): Dette vises best med noen eksempler. Eksempel på en klasse uten bruk av information hiding: Bruk: public class Student { public int age; Student s = new Student();

s.age = 21; Student s2 = new Student(); s2.age = -1; Student s3 = new Student(); s3.age = 213235233; Vi ser at vi står fritt til å angi en alder som ikke gir mening, noe som kan skape feil senere i utførelsen av programmet. Eksempel med bruk av information hiding: public class Student { private int age; boolean setage(int a) { if(a >= 0 && a < 130) { age = a; return true; return false; int getage() { return age; Bruk: Student s = new Student(); int age = 21; if(!s.setage(age)) { System.err.println("Invalid age."); Ved bruk av private, så er det umulig å modifisere age-variabelen direkte utenfor metodene til Student klassen. Modifisering tillates imidlertid i setage-metoden, der en test utføres for å validere om parameteren a holder på en gyldig alder for en student. I tillegg, kan information hiding beskytte oss (programmerer) mot usikkerhet i programmeringen. Eksempel: public class Location2D { // vi ønsker å representere et 2D koordinat. // vi er imidlertid litt usikker på hva som er den beste // representasjonen for dette. Vi starter med to float-verdier: private float x; private float y; public float getx() { return x; public float gety() { return y;

public void setx(float nx) { x = nx; public void sety(float ny) { y = ny; Bruk: // bruk med information hiding: Location2D myloc = new Location2D(); myloc.setx(10.0); myloc.sety(15.0); // bruk uten information hiding (x og y må nå være satt til public): Location2D myloc2 = new Location2D(); myloc2.x = 10.0; myloc2.y = 15.0; La oss nå anta at vi senere i utviklingen har utviklet en egen klasse Vector2D for å representere 2Dkoordinater. Denne nye klassen inneholder nyttige metoder som vi ønsker å bruke, som addisjon og multiplikasjon mellom to 2D koordinater. Vi endrer på klassen vår slik: public class Location2D { // vi bytter representasjonen vår: private Vector2D v; public float getx() { return v.getx(); public float gety() { return v.gety(); public void setx(float nx) { v.setx(nx); public void sety(float ny) { v.sety(ny); Et par endringer har nå blitt gjort i Location2D klassen. Vi har imidlertid ikke endret på signaturen til metodene våre eller lagt til nye metoder etter endringen. Dette betyr at klasser som bruker Location2D ikke må endres på Location2D ble endret lokalt, men på grunn av information hiding, så må ikke andre klasser endres! I programmering, strever vi for å oppnå en struktur som muliggjør at endringer bare må gjøres lokalt i klasser. Konsekvens av bruk: // bruk med information hiding: Location2D myloc = new Location2D(); // må ikke endres: set-metodene tar inn same type // parameter float nx/ny myloc.setx(10.0); myloc.sety(15.0); // bruk uten information hiding: Location2D myloc2 = new Location2D(); // variablene x og y er nå fjernet fra Location2D klassen vår! // De er erstattet med v variabelen.

// Dette gjør at vi må gjøre endringer alle steder som bruker // variablene x og y (som kan være mange hundre steder i et stort // program!) myloc2.x = 10.0; // må endres til myloc2.v.setx(10.0); myloc2.y = 15.0; // må endres til myloc2.v.sety(15.0); Immutability vs. mutability En klasse som er 'mutable' kan endre sine tilstander etter at objektet har blitt opprettet. Dette kan føre til feil og oppførsel som kan være vanskelig å håndtere, spesielt i feiltesting. Et enkelt eksempel: public Person { private String name; public void setname(string n) { name = n; public String getname() { return name; Slike mutable klasser må brukes med forsiktighet. Eksempel: public static void process_person(person p) { p.setname("kari"); public static void main(string[] args) { Person ola = new Person("Ola"); process_person(ola); System.out.println("Name: " + ola.getname()); Her antar vi at brukeren av process_person (i main) ikke ønsker å få endret på tilstanden (fra ola til kari). Selv om dette er et enkelt eksempel for demonstrasjon, viser det seg at klasser som er immutable, det vil si, klasser som defineres slik at tilstandene ikke kan endres på etter opprettelse, har flere fordeler: De er enklere å opprette, teste, og bruke Kan bli brukt i mer kompliserte kodeapplikasjoner, som i tråd-programmering Tilbyr utelukkende "lat" opprettelse (angir tilstander i konstruktør, eng: lazy instantiation) Hvordan definere immutable klasser? Sett alle tilstander til private og påse at ingen tilstander endres på i noen metoder (kan bruke final nøkkelordet). Eksempel med Person: public Person { private final String name; public Person (String n) { name = n; public void setname(string n) { name = n; public String getname() { return name;

Ola må nå opprettes slik: Person ola = new Person("Ola"); Hvis man er tvunget til å definere mutable objekter, så burde man minimalisere graden av mutability. For eksempel, ikke automatisk opprett set-metoder for alle variablene til klassen opprett istedenfor utelukkende set-metoder for de variablene som må kunne endres på etter at objektet har blitt opprettet. Et eksempel på en slik variabel er en poengsum i et objekt som representerer et spill, der poengsummen kan endres på underveis i utføringen av spillet. Et eksempel på en immutable klasse er javas String klasse ser du på metodene til String-klassen vil du ikke finne noen set-metoder eller andre metoder som muliggjør endring av den underliggende char-tabellen.