Ch.9: Objektorientert programmering

Like dokumenter
Objektorientert programmering og løsning av ODE er

Ch.7: Innføring i klasser

Forside. 1 Hva skrives ut?

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

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

INF1000 Eksamen 2014 (modifisert)

Eksamensoppgaver 2014

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

EKSAMENSOPPGAVE / EKSAMENSOPPGÅVE

Objektorientert programmering i Python. Resten av semesteret. Innhold uke 9 Mer komplekse strukturer. Referanser og objekter, inkl Mentimeter spørsmål

Læringsmål uke 7. Introduksjon til objektorientert programmering. Paradigmet objektorientering. Objektreferanser. INF1001 Høst 2016 Uke 7

Objektorientert programmering i Python

Ch.7: Innføring i klasser (del 2)

Klasser og objekter. Tuva Kristine Thoresen 4. november Institutt for Informatikk

INF1000 Eksamen 2014 (modifisert)

Innhold uke 8. Objekter: Bruk og intern organisering. Beskjeder: Oblig 1 6. Beskjeder: Oblig 7 (og 8)

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

EKSAMENSOPPGAVE / EKSAMENSOPPGÅVE

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

Hvorfor objektorientert programmering?

I denne oppgaven skal vi repetere litt Python-syntaks, det er en god blanding av alle tingene du har lært i Python til nå.

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

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

UNIVERSITETET I OSLO

Klasser og objekter. Tuva Kristine Thoresen 21. oktober Institutt for Informatikk

IN1000 Obligatorisk innlevering 7

Repetisjon Novice Videregående Python PDF

AlgDat - Øvingsforelesning 1 Introduksjon til Python, lenkede lister og øving 1

Informasjon Prøveeksamen i IN1000 høsten 2018

Kap 2: Løkker og lister

Seminaroppgaver IN1010, uke 2

UNIVERSITETET I OSLO

Innhold uke 9. Objektorientert programmering i Python. Om ukens pensum. Referanser og objekter Tema: Mer komplekse strukturer

Oppgave 1.6 Hva skrives ut? Riktig svar: The total rainfall from June to August was 54.00

EKSAMENSOPPGAVE. Adm.bygget, rom K1.04 og B154 Ingen. Vil det bli gått oppklaringsrunde i eksamenslokalet? Svar: JA / NEI Hvis JA: ca. kl.

INF1000: Forelesning 7

MAT-INF1100 Oblig 1. Teodor Spæren, brukernavn teodors. September 16, 2015

Informasjon Eksamen i IN1000 høsten 2017

INF1000: Forelesning 7. Konstruktører Static

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


Kondisjonstest. Algoritmer og datastrukturer. Python-oppgaver. Onsdag 6. oktober Her er noen repetisjonsoppgaver i Python.

Kapittel 6: Arv. Redigert av: Khalid Azim Mughal

Løse reelle problemer

EKSAMENSOPPGAVE. : INF-1400 Objektorientert programmering. Oppgavesettet er på 5 sider inklusiv forside

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

TDT Datateknologi, programmeringsprosjekt

UNIVERSITETET I OSLO

Et større programeksempel. Hvordan løse et reelt problem med en objektorientert fremgangsmåte

Oppgave 1.1 (1 poeng) Oppgave 1.2 (2 poeng) Oppgave 1.3 (2 poeng) 1.1

Kap 3: Funksjoner og if-tester

EKSAMEN I INF244: OBJEKTORIENTERT PROGRAMVAREUTVIKLING I BACHELORSTUDIET I IT OG INFORMASJONSSYSTEMER BACHELORSTUDIET I IT OG ENTREPRENØRSKAP

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

Kap3: Klassemodellering

Løsningsveiledning for eksamensoppgaven i INF

Introduksjon til objektorientert programmering

Post-it spørsmål fra timen (Arv og subklasser)

i=0 Repetisjon: arrayer Forelesning inf Java 4 Repetisjon: nesting av løkker Repetisjon: nesting av løkker 0*0 0*2 0*3 0*1 0*4

Informasjon Eksamen i IN1000 og IN1001 høsten a) 1 poeng. 1b) 1 poeng. Tid. Oppgavene. Tillatte hjelpemidler. 30. november kl. 14.

Forelesning inf Java 4

INF våren 2017

Obligatorisk oppgave MAT-INF1100. Lars Kristian Henriksen UiO

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; }

Innhold. INF1000 Høst Unified Modeling Language (UML) Unified Modeling Language (UML)

I dag skal vi ved hjelp av ganske enkel Python-kode finne ut om det er mulig å tjene penger på å selge og kjøpe en aksje.

Innleveringsoppgave 1

Forelesning inf Java 5

UNIVERSITETET I OSLO

Forelesning inf Java 5

Gjennomgang av eksamen H99

INF1000: noen avsluttende ord

TDT4102 Prosedyreog objektorientert programmering Vår 2016

IN våren 2019 Onsdag 16. januar

IN våren 2018 Tirsdag 16. januar

INF2820 Datalingvistikk V2016. Jan Tore Lønning

Klasser, objekter, pekere og UML. INF gruppe 13

To måter å programmere på. Java 12. Programmering med objekter. Statisk programmering

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

Beregning av med svært mange desimaler

UNIVERSITETET I OSLO

Introduksjon til DARK assembly

Finne ut om en løsning er helt riktig og korrigere ved behov

Dagens tema. C-programmering. Nøkkelen til å forstå C-programmering ligger i å forstå hvordan minnet brukes.

UNIVERSITETET I OSLO

INF Obligatorisk innlevering 7 - Hangman

Dark Stakkmaskin. Aritmetiske instruksjoner

UNIVERSITETET I OSLO

UNIVERSITETET I OSLO

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

INF Seminaroppgaver til uke 3

INNFØRING I PRINSIPPER FOR OBJEKTORIENTERT PROGRAMMERING EMILIE HALLGREN OG KRISTIN BRÆNDEN

Anta at følgende programsetninger utføres. Hva skrives ut på skjermen? Hva skrives ut her (skriv nøyaktig de karakterene som printes, og bare de)?

Dagens forelesning. Java 13. Rollefordeling (variant 1) Rollefordeling (variant 2) Design av større programmer : fordeling av roller.

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

UNIVERSITETET I OSLO

EKSAMENSOPPGAVE. INF-1400 Objektorientert Programmering. Dato: Tirsdag 23. mai Klokkeslett: Kl 17:00-21:00. Adm. bygget, Aud.

Tre måter å lese fra terminal. Java 4. Eksempel. Formatert utskrift til skjerm

UNIVERSITETET I OSLO

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

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

Transkript:

Ch.9: Objektorientert programmering Ole Christian Lingjærde, Institutt for Informatikk, UiO 23. oktober 2018

Dagens agenda Mer om klasser Objektorientert programmering

Er du der du skal være? Du bør nå skjønne ganske nøyaktig hva denne klassen gjør: from math import sin class Fnc: def init (self, v0, v1): self.v0 = v0 self.v1 = v1 def call (self, x): return self.v0 * sin(self.v1 * x) def str (self): return 'f(x) = %g * sin(%g*x)' % (self.v0, self.v1) def df(self, x): return self.v0 * self.v1 * cos(self.v1 * x)

Klarer du å svare på følgende spørsmål? Hvor mange attributter og hvor mange metoder har klassen? Hvorfor har noen metoder navn av formen XXXX? Hva er variabelen self? Hvilke metoder i klassen utføres i hver linje nedenfor? f = Fnc(7, 2) print(f) print(f(3.5)) print(f.df(3.5))

Svar To attributter (v0 og v1) og fire metoder Metoder med navn XXXX kalles spesialmetoder. Kall på slike metoder har spesiell syntaks (mer om det senere i dag) Variabelen self er en intern peker til objektet/instansen. Dette er samme peker som returneres til "utsiden" når objektet opprettes. Metodekall som utføres: f = Fnc(7, 2) print(f) print(f(3.5)) print(f.df(3.5)) # Kaller på: init # Kaller på: str # Kaller på: call # Kaller på: df

Klarte du alle spørsmålene? Da er du klar for å gå videre! Møtte du problemer? Ennå ikke for sent, men veldig viktig at du nå tar igjen etterslepet. I dag: bygge videre på det vi har lært om klasser til nå.

UML-diagrammer UML (Unified Modeling Language) er en visuell måte å fremstille og dokumentere datamodeller på. Vi kan bruke UML-diagrammer til å visualisere innholdet i klasser, og relasjoner mellom klasser. Eksempel (for klassen vi nettopp definerte):

Spesialmetoder Spesialmetoder i klasser er strengt tatt aldri nødvendige å bruke Men de gjør ofte at programmer blir mer elegante Krever litt trening å bli kjent med syntaksen

Eksempel A Vi ønsker å definere en klasse Complex hvor objekter representerer komplekse tall med realdel og imaginærdel. De komplekse tallene x = 1 + 2i og z = 2 + i skal kunne lages slik: x = Complex(1,2) og z = Complex(2,1). Vi ønsker å kunne summere to komplekse tall. Vi kunne laget en klassemetode add(self,z) slik at x.add(z) beregner summen x + z. Bedre alternativ: kall metoden add (self,z). Da kan vi addere i Python ved å skrive x + z.

Eksempel A: Matematiske formler La x = a + bi og z = c + di være to komplekse tall. Da er: x + z = (a + c) + (b + d)i x z = (a c) + (b d)i x z = (ac bd) + (ad + bc)i x/z = (ac + bd) + (bc ad)i Hvis klassen Complex har attributter real og imag kan vi dermed få utført addisjonen add (self,z) slik: real = self.real + z.real imag = self.imag + z.imag

Eksempel A: Python-kode class Complex: def init (self, real, imag): self.real = float(real) self.imag = float(imag) def str (self): s = '%g + %gi' % (self.real, self.imag) return s def add (self, z): real = self.real + z.real imag = self.imag + z.imag res = Complex(real, imag) return res # Eksempel på bruk: x = Complex(1,2) y = Complex(2,1) z = x + y # Ekvivalent: z = Complex. add (x,y) print(z)

Eksempel B Anta at vi har klassen Complex fra forrige eksempel Vi kan bruke samme "trikset" til å definere alle fire regnearter Vi kan bruke spesialfunksjonene sub, mul og div på samme måte som vi har brukt add

Eksempel B: Python-kode class Complex: <Alt tidligere som før> def sub (self, z): real = self.real - z.real imag = self.imag - z.imag res = Complex(real, imag) return res def mul (self, z): real = self.real*z.real - self.imag*z.imag imag = self.real*z.imag + self.imag*z.real res = Complex(real, imag) return res def div (self, z): r = z.real**2 + z.imag**2 real = (self.real*z.real + self.imag*z.imag)/r imag = (self.imag*z.real - self.real*z.imag)/r res = Complex(real, imag) return res

Eksempler på bruk x = Complex(1,1) # x = 1 + i y = Complex(2,3) # y = 2 + 3i print(x + y) print(x - y) print(x * y) print(x / y) print(x * y / y) # 3 + 4i # -1-2i # -1 + 5i # 0.384615 + -0.0769231i # 1 + 1i

Noen viktige spesialmetoder a. init (self, args) # Konstruktør a. del (self) # Destruktør a. call (self, args) # Funksjonskall a. str (self) # Tekstrepresentasjon a. repr (self) # a = eval(repr(a)) a. add (self, b) # a + b a. sub (self, b) # a - b a. mul (self, b) # a * b a. div (self, b) # a / b a. pow (self, b) # a ** b a. lt (self, b) # a < b a. le (self, b) # a <= b a. gt (self, b) # a > b a. ge (self, b) # a >= b a. eq (self, b) # a == b a. ne (self, b) # a!= b

Objektorientert programmering (OOP) Alt i Python er objekter, så teknisk sett er all Python-programmering objektbasert. I objektorientert programmering (OOP) går vi ett skritt videre. OOP utnytter en svært nyttig egenskap ved klasser: de kan settes sammen som byggeklosser! Hvis vi har definert en klasse class A så kan vi definere en ny klasse class B(A). Da blir klassen B en utvidelse av klassen A Vi sier at B arver data og metoder fra A Vi sier også at B er subklasse av A, og at A er superklasse til B

Prinsipp A: Klasser kan arve fra andre klasser class A: def init (self, v0, v1): self.v0 = v0 self.v1 = v1 def f(self, x): return x**2 class B(A): def g(self, x): return x**4 class C(B): def h(self, x): return x**6 Vi har nå definert tre klasser: A : to attributter (v0, v1) og to metoder ( init, f) B : to attributter (v0, v1) og tre metoder ( init, f, g) C : to attributter (v0, v1) og fire metoder ( init, f, g, h)

UML-diagram

Innholdet i klassene A, B og C # I objekter av A har vi attributtene v0, v1 og metoden f: p = A(2.7, 5.2) print(p.v0) # Utskrift: 2.7 print(p.v1) # Utskrift: 5.2 print(p.f(3.0)) # Utskrift: 9.0 # I objekter av B har vi det samme + metoden g: p = B(2.7, 5.2) print(p.v0) # Utskrift: 2.7 print(p.v1) # Utskrift: 5.2 print(p.f(3.0)) # Utskrift: 9.0 print(p.g(3.0)) # Utskrift: 81.0 # I objekter av C har vi det samme + metoden h: p = C(2.7, 5.2) print(p.v0) # Utskrift: 2.7 print(p.v1) # Utskrift: 5.2 print(p.f(3.0)) # Utskrift: 9.0 print(p.g(3.0)) # Utskrift: 81.0 print(p.h(3.0)) # Utskrift: 729.0

Prinsipp B: Subklasser kan overkjøre metoder i superklasser class A: def init (self, a): self.a = a def skrivut(self): print("klasse A") class B(A): def init (self, b): self.b = b def skrivut(self): print("klasse B") # Overkjører init i class A # Overkjører skrivut i class A # Eksempler på bruk p = A(3) # Lag objekt av superklassen A p.skrivut() # Utskrift: "Klasse A" p = B(4) # Lag objekt av subklassen B p.skrivut() # Utskrift: "Klasse B"

Hensikten med å overkjøre metoder Subklasser kan brukes for å legge til ny funksjonalitet. Da kan det tenkes at vi har behov for å definere enda flere instansvariable med konstruktøren. Da må denne defineres på nytt i subklassen. Subklasser kan også brukes for å restriktere funksjonaliteten i klassen det arves fra. Da kan det tenkes at vi trenger å initialisere noen av instansvariablene i superklassen til 0. Da må konstruktøren også defineres på nytt. Utskrift og andre funksjoner kan også være nødvendig å endre i subklasser. Kommer til å bli klarere etterhvert som vi ser eksempler

Prinsipp C: Overkjørte metoder finnes fortsatt class A: def init (self, a): self.a = a def skrivut(self): print("klasse A") class B(A): def init (self, a, b): A. init (self, a) self.b = b # Kall init i superklassen def skrivut(self): A.skrivut(self) print("klasse B") # Kall skrivut i superklassen p = B(3,4) # Lag objekt av subklassen B p.skrivut() # Utskrift: 'Klasse A' + linjeskift + 'Klasse B'

Prinsipp D: Vi kan ha mange nivåer av subklasser class A: def init (self, a): self.a = a def skrivut(self): print('a = %g' % self.a) class B(A): def init (self, a, b): A. init (self, a) self.b = b def skrivut(self): print('a = %g, b = %g' % (self.a, self.b)) class C(B): def init (self, a, b, c): B. init (self, a, b) self.c = c def skrivut(self): print('a = %g, b = %g, c = %g' % (self.a, self.b, self.c)) p1 = A(1) p1.skrivut() # a = 1 p2 = B(1,2) p2.skrivut() # a = 1, b = 2 p3 = C(1,2,3) p3.skrivut() # a = 1, b = 2, c = 3

Prinsipp E: Vi kan alltid finne ut hvor vi er i hierarkiet Anta at klassene A, B, C er definert som på forrige slide. # Lag objekter av A og B p = A(1) q = B(1,2) # Hvilke klasser er et objekt en instans av? isinstance(p, A) # True isinstance(p, B) # False isinstance(q, A) # True isinstance(q, B) # True # Hvilken unike klasse tilhører objektet p? print(p. class == A) # True print(p. class == B) # False print(q. class == A) # False print(q. class == B) # True # Alternativ til over print(p. class. name == 'A') # True # Er klassen B en subklasse av klassen A? issubclass(b, A) # True issubclass(a, B) # False # Finn navnet på superklassen til et objekt print(q. class. bases [0]. name ) # A

Eksempel A: Person <- Ansatt class Person: def init (self, navn, fnr, adr): self.navn = navn self.fnr = fnr self.adr = adr def str (self): s = 'Navn: %s\nfnr: %s\nadresse: %s\n' % \ (self.navn, self.fnr, self.adr) return s class Ansatt(Person): def init (self, navn, fnr, adr, stilling): Person. init (self, navn, fnr, adr) self.stilling = stilling def str (self): s1 = Person. str (self) s2 = 'Stilling: %s\n' % self.stilling return(s1 + s2) p = Person('Rex', '18050012345', 'Slottet') print(p) p = Ansatt('Rex', '18050012345', 'Slottet', 'Konge') print(p)

UML-diagram

Eksempel B: Fnc <- DiffFnc from math import sin, cos class Fnc: def init (self, a, b): self.a = a self.b = b def call (self, x): res = self.a*sin(x) + self.b*cos(x) return res class DiffFnc(Fnc): def init (self, a, b, h=1e-5): Fnc. init (self, a, b) self.h = h def df(self, x): res = self.a*cos(x) - self.b*sin(x) return res # f = Fnc(2,6) print(f(3)) # -5.65771496348 # f = DiffFnc(2,6) print(f(3)) # -5.65771496348 print(f.df(3)) # -2.82670504156

UML-diagram

Eksempel C: Linear <- Quadratic class Linear: def init (self, c0, c1): self.c0 = c0 self.c1 = c1 def call (self, x): return self.c0 + self.c1*x class Quadratic(Linear): def init (self, c0, c1, c2): Linear. init (self, c0, c1) self.c2 = c2 def call (self, x): return Linear. call (self, x) + self.c2*x**2 # Test av klassene p = Quadratic(3, 4, 5) print(p(2.5)) # 44.25

UML-diagram

Eksempel D: Location <- Point import matplotlib.pyplot as plt class Location: def init (self, x, y): self.x = x; self.y = y def str (self): return '(%g, %g)' % (self.x, self.y) class Point(Location): def init (self, x, y, plotstyle='ro'): Location. init (self, x, y) self.plotstyle = plotstyle def add (self, p): xnew = self.x + p.x ynew = self.y + p.y return Point(xnew, ynew) def plot(self): plt.plot(self.x, self.y, self.plotstyle) p1 = Point(3,4); p2 = Point(1,1); p3 = Point(2.5, 1.5) p4 = p1 + p3 p1.plot(); p2.plot(); p3.plot(); p4.plot()

UML-diagram

Eksempel E: Derivatives <- SinCos from math import sin, cos class Derivatives: def init (self, h=1e-5): self.h = float(h) def call (self, x): print('not implemented in this class!') def df(self, x): return (self(x+self.h)-self(x-self.h))/(2*self.h) def ddf(self, x): return (self(x+self.h)-2*self(x)+self(x-self.h))/(self.h**2) class SinCos(Derivatives): def init (self, a, b): Derivatives. init (self) self.a = a; self.b = b def call (self, x): return self.a * cos(x) + self.b * sin(x) f = SinCos(3, 6); x = 0.5 print('f(%g) = %g' % (x, f(x))) print('df(%g) = %g' % (x, f.df(x))) print('ddf(%g) = %g' % (x, f.ddf(x)))

UML-diagram