80
15 Objektorientiertes Programmieren Objektorientiertes Programmieren (OOP) basiert auf Objekten: zusammengesetzten Datenstrukturen mit gekapseltem Zustand Operationen auf dem Zustand, den Methoden Vererbung: (inheritance ) ein Konzept zur Erweiterung von Zustand und Funktionalit¨ at von Objekten Message passing: ein Konzept zum Finden der Komponente eines Objekts, die f¨ ur einen Methodenaufruf zust¨ andig ist

15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Embed Size (px)

Citation preview

Page 1: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

15 Objektorientiertes Programmieren

Objektorientiertes Programmieren (OOP) basiert auf

Objekten: zusammengesetzten Datenstrukturen mit

• gekapseltem Zustand

• Operationen auf dem Zustand, den Methoden

Vererbung: (inheritance) ein Konzept zur Erweiterung von Zustand und

Funktionalitat von Objekten

Message passing: ein Konzept zum Finden der Komponente eines Objekts, die fur

einen Methodenaufruf zustandig ist

Vorlaufige Version 386 c© 2007 Peter Thiemann

Page 2: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

15.1 Einfaches Bankkonto als Objekt

Erinnerung: Konto mit gekapseltem Zustand und separater withdraw Operation

; Geld abheben und anzeigen, ob das moglich war

; account-withdraw : account number -> boolean

; Effekt: (account-withdraw a n) andert den Kontostand von a

(define account-withdraw

(lambda (a n)

(if (>= (account-balance a) n)

(begin

(set-account-balance! a (- (account-balance a) n))

#t)

#f)))

• Beobachtung:

– Das account Objekt muss als Parameter mitgegeben werden.

– Andere Prozeduren konnen auch account Objekte bearbeiten.

• Objektorientierter Ansatz: account so verpacken, dass es nur durch die Prozedur

withdraw bearbeitet werden kann

Vorlaufige Version 387 c© 2007 Peter Thiemann

Page 3: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Spezifikation: Bankkonto als Objekt

• Ein Kontoobjekt ist eine Prozedur mit Vertrag

account = number -> (number or #f)

Die Prozedur hebt einen Geldbetrag ab und liefert #f, falls das Geld nicht

verfugbar ist. Ansonsten liefert sie den Kontostand nach dem Abheben.

Effekt: Der Kontostand wird geandert.

• Argument 0 liefert den aktuellen Kontostand.

; Konto aus Geldbetrag erzeugen

; make-account : number -> account

(define make-account

(lambda (balance)

...))

Vorlaufige Version 388 c© 2007 Peter Thiemann

Page 4: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Implementierung: Bankkonto als Objekt

; Konto aus Geldbetrag erzeugen

; make-account : number -> account

; make-account : number -> (number -> (number or #f))

(define make-account

(lambda (balance)

;; das account Objekt ist die Abhebeprozedur!

(lambda (amount)

(if (<= amount balance)

(begin

(set! balance (- balance amount))

balance)

#f))))

Vorlaufige Version 389 c© 2007 Peter Thiemann

Page 5: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Beispiel: Bankkonto als Objekt

> (define acc1 (make-account 1000))

> acc1

#<procedure>

> (acc1 0) ; Kontostand abfragen

1000

> (acc1 200) ; abheben

800

> (acc1 1000) ; mehr abheben

#f

> (acc1 0) ; Kontostand

0

Vorlaufige Version 390 c© 2007 Peter Thiemann

Page 6: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Beispiel mit Bankkonto/1

Speicher

Bindungen

Kommandosequenz

(define acc1 (make-account 1000))

acc1

(acc1 0)

(acc1 200)

(acc1 1000)

Vorlaufige Version 391 c© 2007 Peter Thiemann

Page 7: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Beispiel mit Bankkonto/2

Speicher

Bindungen

Kommandosequenz

(define acc1 ((lambda (balance) (lambda (amount) ...)) 1000))

acc1

(acc1 0)

(acc1 200)

(acc1 1000)

Vorlaufige Version 392 c© 2007 Peter Thiemann

Page 8: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Beispiel mit Bankkonto/3

Speicher

L1000 |-> 1000

Bindungen

Kommandosequenz

(define acc1 (lambda (amount)

(if (<= amount L1000)

(begin

(set! L1000 (- L1000 amount))

L1000)

#f)))

acc1

(acc1 0)

(acc1 200)

(acc1 1000)

Vorlaufige Version 393 c© 2007 Peter Thiemann

Page 9: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Beispiel mit Bankkonto/4

Speicher

L1000 |-> 1000

L2 |-> (lambda (amount)

(if (<= amount L1000)

(begin

(set! L1000 (- L1000 amount))

L1000)

#f))

Bindungen

acc1 = L2

Kommandosequenz

acc1 ; #<procedure>

(acc1 0)

(acc1 200)

(acc1 1000)

Vorlaufige Version 394 c© 2007 Peter Thiemann

Page 10: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Beispiel mit Bankkonto/5

Speicher

L1000 |-> 1000

L2 |-> (lambda (amount) ...)

Bindungen

acc1 = L2

Kommandosequenz

((lambda (amount)

(if (<= amount L1000)

(begin

(set! L1000 (- L1000 amount))

L1000)

#f)) 0)

(acc1 200)

(acc1 1000)

Vorlaufige Version 395 c© 2007 Peter Thiemann

Page 11: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Beispiel mit Bankkonto/6

Speicher

L1000 |-> 1000

L2 |-> (lambda (amount) ...)

L0 |-> 0

Bindungen

acc1 = L2

Kommandosequenz

(if (<= L0 L1000)

(begin

(set! L1000 (- L1000 L0))

L1000)

#f)

(acc1 200)

(acc1 1000)

Vorlaufige Version 396 c© 2007 Peter Thiemann

Page 12: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Beispiel mit Bankkonto/7

Speicher

L1000 |-> 1000

L2 |-> (lambda (amount) ...)

L0 |-> 0

Bindungen

acc1 = L2

Kommandosequenz

(if (<= 0 1000)

(begin

(set! L1000 (- L1000 L0))

L1000)

#f)

(acc1 200)

(acc1 1000)

Vorlaufige Version 397 c© 2007 Peter Thiemann

Page 13: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Beispiel mit Bankkonto/8

Speicher

L1000 |-> 1000

L2 |-> (lambda (amount) ...)

L0 |-> 0

Bindungen

acc1 = L2

Kommandosequenz

(begin

(set! L1000 (- L1000 L0))

L1000)

(acc1 200)

(acc1 1000)

Vorlaufige Version 398 c© 2007 Peter Thiemann

Page 14: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Beispiel mit Bankkonto/9

Speicher

L1000 |-> 1000

L2 |-> (lambda (amount) ...)

L0 |-> 0

Bindungen

acc1 = L2

Kommandosequenz

(begin

(set! L1000 (- 1000 0))

L1000)

(acc1 200)

(acc1 1000)

Vorlaufige Version 399 c© 2007 Peter Thiemann

Page 15: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Beispiel mit Bankkonto/10

Speicher

L1000 |-> 1000

L2 |-> (lambda (amount) ...)

L0 |-> 0

Bindungen

acc1 = L2

Kommandosequenz

(begin

(set! L1000 1000)

L1000)

(acc1 200)

(acc1 1000)

Vorlaufige Version 400 c© 2007 Peter Thiemann

Page 16: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Beispiel mit Bankkonto/11

Speicher

L1000 |-> 1000

L2 |-> (lambda (amount) ...)

L0 |-> 0

Bindungen

acc1 = L2

Kommandosequenz

(begin

L1000)

(acc1 200)

(acc1 1000)

Vorlaufige Version 401 c© 2007 Peter Thiemann

Page 17: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Beispiel mit Bankkonto/12

Speicher

L1000 |-> 1000

L2 |-> (lambda (amount) ...)

L0 |-> 0

Bindungen

acc1 = L2

Kommandosequenz

1000

(acc1 200)

(acc1 1000)

Vorlaufige Version 402 c© 2007 Peter Thiemann

Page 18: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Beispiel mit Bankkonto/13

Speicher

L1000 |-> 1000

L2 |-> (lambda (amount) ...)

L0 |-> 0

Bindungen

acc1 = L2

Kommandosequenz

1000

((lambda (amount)

(if (<= amount L1000)

(begin

(set! L1000 (- L1000 amount))

L1000)

#f)) 200)

(acc1 1000)

Vorlaufige Version 403 c© 2007 Peter Thiemann

Page 19: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Beispiel mit Bankkonto/14

Speicher

L1000 |-> 1000

L2 |-> (lambda (amount) ...)

L0 |-> 0

L200 |-> 200

Bindungen

acc1 = L2

Kommandosequenz

1000

(if (<= L200 L1000)

(begin

(set! L1000 (- L1000 L200))

L1000)

#f)

(acc1 1000)

Vorlaufige Version 404 c© 2007 Peter Thiemann

Page 20: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Beispiel mit Bankkonto/15

Speicher

L1000 |-> 1000

L2 |-> (lambda (amount) ...)

L0 |-> 0

L200 |-> 200

Bindungen

acc1 = L2

Kommandosequenz

1000

(begin

(set! L1000 (- L1000 L200))

L1000)

(acc1 1000)

Vorlaufige Version 405 c© 2007 Peter Thiemann

Page 21: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Beispiel mit Bankkonto/16

Speicher

L1000 |-> 1000

L2 |-> (lambda (amount) ...)

L0 |-> 0

L200 |-> 200

Bindungen

acc1 = L2

Kommandosequenz

1000

(begin

(set! L1000 800)

L1000)

(acc1 1000)

Vorlaufige Version 406 c© 2007 Peter Thiemann

Page 22: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Beispiel mit Bankkonto/17

Speicher

L1000 |-> 800

L2 |-> (lambda (amount) ...)

L0 |-> 0

L200 |-> 200

Bindungen

acc1 = L2

Kommandosequenz

1000

L1000

(acc1 1000)

Vorlaufige Version 407 c© 2007 Peter Thiemann

Page 23: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Beispiel mit Bankkonto/18

Speicher

L1000 |-> 800

L2 |-> (lambda (amount) ...)

L0 |-> 0

L200 |-> 200

Bindungen

acc1 = L2

Kommandosequenz

1000

800

(acc1 1000)

Vorlaufige Version 408 c© 2007 Peter Thiemann

Page 24: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

15.2 Bankkonto mit mehreren Operationen

(define make-account

(lambda (balance)

;; Abheben

(lambda (amount)

(if (<= amount balance)

(begin

(set! balance (- balance amount))

balance)

#f))))

• Das einfache Bankkonto erlaubt nur eine Operation, das Abheben.

• Weitere Operationen (z.B. Kontostand) mussen Zugriff auf balance haben.

• Wo mussen diese Operationen eingefugt werden?

Vorlaufige Version 409 c© 2007 Peter Thiemann

Page 25: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Bankkonto mit Kontostand (unvollstandig)

(define make-account

(lambda (balance)

...

;; Kontostand

(lambda ()

balance)

...

;; Abheben

(lambda (amount)

(if (<= amount balance)

(begin

(set! balance (- balance amount))

balance)

#f))))

• balance ist nur im Rumpf von (lambda (balance) ...) sichtbar

Vorlaufige Version 410 c© 2007 Peter Thiemann

Page 26: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Message Passing

• Auswahl zwischen den Operationen fur Kontostand und Abheben notwendig

• Implementiert durch separate Prozedur (message dispatcher)

• Eingabe: Nachricht (message) mit dem Namen der gewunschten Operation

• Ausgabe: die ausgewahlte Operation

• Furs Bankkonto:

– Nachrichten sind die Strings "balance" und "withdraw"

– Vertrag der Prozedur ist

("balance" -> ( -> number))

and

("withdraw" -> (number -> (number or #f)))

Vorlaufige Version 411 c© 2007 Peter Thiemann

Page 27: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Bankkonto mit Message Passing

(define make-account

(lambda (balance)

(lambda (message)

(cond

;; Kontostand

((string=? message "balance")

(lambda ()

balance))

;; Abheben

((string=? message "withdraw")

(lambda (amount)

(if (<= amount balance)

(begin

(set! balance (- balance amount))

balance)

#f)))))))

Vorlaufige Version 412 c© 2007 Peter Thiemann

Page 28: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Verwendung: Bankkonto mit MP

> (define acc (make-account 5000))

> acc ; (lambda (message) ...)

#<procedure>

> (acc "withdraw") ; (lambda (amount) ...)

#<procedure>

> ((acc "withdraw") 10)

4990

> (acc "balance") ; (lambda () balance)

#<procedure>

> ((acc "balance"))

4990

Vorlaufige Version 413 c© 2007 Peter Thiemann

Page 29: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

15.3 Versenden von Nachrichten

• Die Aufrufe der Operationen sind sperrig:

– ((acc "balance"))

– ((acc "withdraw") 77)

• Abhilfe: Definiere Prozedur send, so dass

– (send acc "balance")

– (send acc "withdraw" 77)

• Beobachtung: Die Aufrufe von send brauchen unterschiedlich viele Parameter

Vorlaufige Version 414 c© 2007 Peter Thiemann

Page 30: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Definition von send

; verschicken einer Nachricht an ein Objekt

; send : object string value* -> value

(define send

(lambda (obj message . args)

(apply (obj message) args)))

Neues:

• (lambda (obj message . args) ...)

– Prozedur, die mindestens zwei Parameter akzeptiert

– beliebig viele weitere Parameter werden in der Liste args zusammengefasst

– Sonderfall: (lambda args 〈body〉) erwartet beliebig viele Argumente

• (apply f args)

– wendet f auf die Argumentliste args an

– f muss genausoviele Parameter erwarten, wie args Elemente hat

Vorlaufige Version 415 c© 2007 Peter Thiemann

Page 31: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Verwendung: Bankkonto mit MP und send

> (define acc (make-account 5000))

> acc ; (lambda (message) ...)

#<procedure>

> (acc "withdraw") ; (lambda (amount) ...)

#<procedure>

> (send acc "withdraw" 10)

4990

> (acc "balance") ; (lambda () balance)

#<procedure>

> (send acc "balance")

4990

Vorlaufige Version 416 c© 2007 Peter Thiemann

Page 32: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

15.4 Vererbung

• Codierung von Objekten: siehe acc

• make-account erzeugt Objekte

• Sie kann als Klasse angesehen werden:

– Klasse als Objektgenerator

– Argumente der Klasse spezifizieren den Objektzustand

– Prozedur im message dispatcher spezifizieren die Operationen (Methoden)

• Methodenaufruf durch message passing

• Jetzt: Erweiterungsmechanismus”Vererbung“

Vorlaufige Version 417 c© 2007 Peter Thiemann

Page 33: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Personen

Eine Person besitzt drei Operationen

1. get-name: Sie kann ihren Namen angeben.

2. say: Sie kann sprechen (indem sie den Text ausdruckt).

3. slap: Sie soll Schlage einstecken, auf die sie jeweils durch ”huh?” reagiert; bei

jedem dritten Schlag kommt ”ouch!”.

D.h. der Zustand eines Personenobjekts enthalt zumindest den Namen.

Vorlaufige Version 418 c© 2007 Peter Thiemann

Page 34: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Person mit MP (1. Naherung)

; Person konstruieren

; make-person : string -> (message -> method)

(define make-person

(lambda (name)

(lambda (message)

(cond

((string=? message "get-name")

;; Namen liefern

;; -> string

(lambda ()

name))

((string=? message "say")

;; Text ausdrucken

;; list(string) -> unspecified

(lambda (text)

(write-list-newline text)))))))

Vorlaufige Version 419 c© 2007 Peter Thiemann

Page 35: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Hilfsprozedur write-list-newline

; Drucke Liste von Strings

; write-list-newline : list(string) -> unspecified

(define write-list-newline

(lambda (text)

(begin

(for-each (lambda (s) (write-string s)) text)

(write-newline))))

Dabei ist

• write-string : string -> unspecified druckt einen String aus

• write-newline : -> unspecified druckt einen Zeilenvorschub

• for-each : (a -> b) list(a) -> unspecified

(for-each f xs) wendet f von Beginn der Liste xs auf alle Elemente an

Vorlaufige Version 420 c© 2007 Peter Thiemann

Page 36: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Probelauf

> (define sarah (make-person "Sarah"))

> (send sarah "get-name")

"Sarah"

> (send sarah "say" (list "I’m" " " "so" " " "clever"))

I’m so clever

Vorlaufige Version 421 c© 2007 Peter Thiemann

Page 37: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Die slap Operation

• Benotigt eine weitere Variable fur die Anzahl der bisher eingesteckten Schlage

• Die gesprochene Reaktion soll nicht uber write-list-newline erfolgen, sondern

unter Verwendung der eigenen Operation say

• Problem dabei: wie wird say aufgerufen?

Vorlaufige Version 422 c© 2007 Peter Thiemann

Page 38: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Person mit slap (2. Naherung)

(define make-person

(lambda (name)

(let ((slaps 0)) ; Anzahl der Schlage

(lambda (message)

(cond

((string=? message "get-name") ...)

((string=? message "say") ...)

((string=? message "slap")

(lambda ()

(begin

(set! slaps (+ slaps 1))

(if (< slaps 3)

(send ... "say" (list "huh?"))

(begin

(set! slaps 0)

(send ... "say" (list "ouch!"))))))))))))

Vorlaufige Version 423 c© 2007 Peter Thiemann

Page 39: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Self

• Der Empfanger von say muss das Objekt selbst sein

• Das Objekt selbst wird durch (lambda (message) ...) reprasentiert

⇒ Diese Prozedur muss mit letrec lokal rekursiv definiert werden!

• Traditionelle Name fur das Objekt selbst:

– self (in Smalltalk, hier)

– this (in C++, Java, usw)

Vorlaufige Version 424 c© 2007 Peter Thiemann

Page 40: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Person mit slap (endgultig)

(define make-person

(lambda (name)

(let ((slaps 0)) ; Anzahl der Schlage

(letrec ((self

(lambda (message)

(cond

((string=? message "get-name") ...)

((string=? message "say") ...)

((string=? message "slap")

(lambda ()

(begin

(set! slaps (+ slaps 1))

(if (< slaps 3)

(send self "say" (list "huh?"))

(begin

(set! slaps 0)

(send self "say" (list "ouch!")))))))))))

self))))

Vorlaufige Version 425 c© 2007 Peter Thiemann

Page 41: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Person in Aktion

> (define sarah (make-person "Sarah"))> (send sarah "slap")huh?> (send sarah "slap")huh?> (send sarah "slap")ouch!> (send sarah "slap")huh?

425-1

Page 42: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Sanger

• Ein Sanger ist eine Person mit zusatzlichen Fahigkeiten

– Es gibt alle Methoden von Person

– zusatzlich die Methode sing, die einen Text singt.

Ansatz:

; Sanger konstruieren

; make-singer : string -> (message -> method)

(define make-singer

(lambda (name)

(let ((person (make-person name)))

...)))

Vorlaufige Version 426 c© 2007 Peter Thiemann

Page 43: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Sanger mit sing (1. Naherung)

; Sanger konstruieren

; make-singer : string -> (message -> method)

(define make-singer

(lambda (name)

(let ((person (make-person name)))

(letrec ((self

(lambda (message)

(cond

((string=? message "sing")

;; Text singen

;; list(string) -> unspecified

...)

...))))

self))))

• Die Nachricht sing wird verarbeitet

• Was passiert mit get-name, say und slap?

Vorlaufige Version 427 c© 2007 Peter Thiemann

Page 44: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Sanger mit sing (2. Naherung)

; Sanger konstruieren

; make-singer : string -> (message -> method)

(define make-singer

(lambda (name)

(let ((person (make-person name)))

(letrec ((self

(lambda (message)

(cond

((string=? message "sing")

;; Text singen

;; list(string) -> unspecified

...)

(else (person message))))))

self))))

• get-name, say und slap werden an person delegiert

• sing wird unter Ruckgriff auf say implementiert

Vorlaufige Version 428 c© 2007 Peter Thiemann

Page 45: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Sanger mit sing (endgultig)

; Sanger konstruieren

; make-singer : string -> (message -> method)

(define make-singer

(lambda (name)

(let ((person (make-person name)))

(letrec ((self

(lambda (message)

(cond

((string=? message "sing")

;; Text singen

;; list(string) -> unspecified

(lambda (text)

(send self "say" (make-pair "tra-la-la " text))))

(else (person message))))))

self))))

Vorlaufige Version 429 c© 2007 Peter Thiemann

Page 46: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Sanger(in) in Aktion

> (define sarah (make-singer "Sarah"))

> (send sarah "say" (list "hi"))

hi

> (send sarah "sing" (list "hi"))

tra-la-la hi

Vorlaufige Version 430 c© 2007 Peter Thiemann

Page 47: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Einfache Vererbung (Single Inheritance)

• Konstruktion eines Objekts, das alle Eigenschaften (Methoden und Zustand) eines

anderen Objekts hat und noch weitere dazu

• Bsp: Sanger hat alle Eigenschaften von Person und besitzt Methode sing

• make-singer und make-person spielen die Rolle von Klassen

• Person ist Oberklasse von Sanger (superclass)

• Sanger ist Unterklasse von Person (subclass)

• Ein Objekt, das von einer Klasse erzeugt wurde, heißt Instanz der Klasse

Bsp: sarah

• Lokale Variable einer Instanz heißen Instanzvariable

Bsp: slaps

Vorlaufige Version 431 c© 2007 Peter Thiemann

Page 48: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Einfuhren von einfacher Vererbung

• Klassenhierarchie

– Eine Klasse kann mehrere Unterklassen besitzen

– Jede Unterklasse kann selbst wieder Unterklassen besitzen

• Die Aufteilung der Eigenschaften zwischen Ober- und Unterklasse wird beim

Programmentwurf festgelegt

• Ausgehend von einer Menge von benotigten Klassen werden Oberklassen definiert,

die gemeinsame Eigenschaften der Klassen zusammenfassen.

• Nicht ubertreiben: Klassenhierarchie sollte nicht zu feingranular sein

#15 (Oberklassen)

Fasse Gemeinsamkeiten von Klassen in Oberklassen zusammen.

Vorlaufige Version 432 c© 2007 Peter Thiemann

Page 49: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Klassendiagramm

• Graphische Darstellung von Vererbungshierarchien

Person

Singer Skater Softie

Rockstar

Vorlaufige Version 433 c© 2007 Peter Thiemann

Page 50: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

15.5 Uberschreiben von Methoden

• Im Zuge der Vererbung konnen Methoden uberschrieben werden (method override)

• Klasse definiert neue Implementierung einer Methode einer Oberklasse

• Vorsicht: die Funktion dieser Methode kann beliebig geandert werden!

• Beispiel: Ein Rockstar ist ein Sanger, der

– an alles, was er sagt, noch ", dude" anhangt und

– auf Schlage anders als ein normaler Mensch reagiert.

Vorlaufige Version 434 c© 2007 Peter Thiemann

Page 51: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Beispiel: Rockstar

; Rockstar erzeugen

; make-rockstar : string -> (message -> method)

(define make-rockstar

(lambda (name)

(let ((singer (make-singer name)))

(letrec ((self

(lambda (message)

(cond

((string=? message "say")

;; Text sprechen

;; list(string) -> unspecified

(lambda (text)

(send singer "say" (append text (list ", dude")))))

((string=? message "slap")

;; Schlag einstecken

;; -> unspecified

(lambda ()

(send self "say" (list "pain just makes me stronger"))))

(else (singer message))))))

self))))

Vorlaufige Version 435 c© 2007 Peter Thiemann

Page 52: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Rockstar in Aktion

> (define marilyn (make-rockstar "Marilyn"))

> (send marilyn "say" (list "hello"))

hello, dude

> (send marilyn "slap")

pain just makes me stronger, dude

> (send marilyn "sing" (list "happy birthday smurfs"))

tra-la-la happy birthday smurfs

• Unerwartet: die sing Methode hangt kein ", dude" an!

• Warum?

• Wie kann das repariert werden?

Vorlaufige Version 436 c© 2007 Peter Thiemann

Page 53: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Mache self zum Parameter jeder Methode!

(define make-person

(lambda (name)

(let ((slaps 0))

(lambda (message)

(cond

((string=? message "get-name")

;; person -> string

(lambda (self)

name))

((string=? message "say")

;; person list(string) -> unspecified

(lambda (self text)

(write-list-newline text)))

((string=? message "slap")

;; person -> unspecified

(lambda (self)

(begin

(set! slaps (+ slaps 1))

(if (< slaps 3)

(send self "say" (list "huh?"))

(begin

(send self "say" (list "ouch!"))

(set! slaps 0)))))))))))

Vorlaufige Version 437 c© 2007 Peter Thiemann

Page 54: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Erweiterung von send

Alte Implementierung

; verschicken einer Nachricht an ein Objekt

; send : object string value* -> value

(define send

(lambda (obj message . args)

(apply (obj message) args)))

Neue Implementierung

; verschicken einer Nachricht an ein Objekt

; send : object string value* -> value

(define send

(lambda (obj message . args)

(apply (obj message) obj args)))

• Verwendet erweitertes apply (mit mehr als zwei Argumenten)

Vorlaufige Version 438 c© 2007 Peter Thiemann

Page 55: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Erweiterung von apply

• (apply f a1 ...an args)

– wendet f auf a1 ... an sowie weitere Parameter aus Argumentliste args an

– f muss (+ n (length args)) Parameter erwarten

Beispiel:

> (apply / 120 (list))

0.0083

> (apply / 120 (list 1))

120

> (apply / 120 (list 1 2))

60

> (apply / 120 (list 1 2 3))

20

> (apply / 120 (list 1 2 3 4))

5

> (apply / 120 (list 1 2 3 4 5))

1

Vorlaufige Version 439 c© 2007 Peter Thiemann

Page 56: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Korrigierter Sanger

(define make-singer

(lambda (name)

(let ((person (make-person name)))

(lambda (message)

(cond

((string=? message "sing")

;; Text singen

;; singer list(string) -> unspecified

(lambda (self text)

(send self "say" (make-pair "tra-la-la " text))))

(else (person message)))))))

Vorlaufige Version 440 c© 2007 Peter Thiemann

Page 57: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Korrigierter Rockstar

(define make-rockstar

(lambda (name)

(let ((singer (make-singer name)))

(lambda (message)

(cond

((string=? message "say")

;; Text sagen

;; rockstar list(string) -> unspecified

(lambda (self text)

(send singer "say" (append text (list ", dude")))))

((string=? message "slap")

;; Schlag einstecken

;; rockstar -> unspecified

(lambda (self)

(send self "say" (list "pain just makes me stronger"))))

(else (singer message)))))))

Vorlaufige Version 441 c© 2007 Peter Thiemann

Page 58: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Korrigierter Rockstar in Aktion

> (define marilyn (make-rockstar "Marilyn"))

> (send marilyn "say" (list "hello"))

hello, dude

> (send marilyn "slap")

pain just makes me stronger, dude

> (send marilyn "sing" (list "happy birthday smurfs"))

go smurfy go, dude

Analyse der Methodenaufrufe

• say wird uberschrieben und ruft singer.say auf

• slap wird uberschrieben und ruft self.say (rockstar.say) auf

• sing wird an singer.sing weiter gereicht;

dort wird jetzt self.say (rockstar.say) aufgerufen

Vorlaufige Version 442 c© 2007 Peter Thiemann

Page 59: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Analyse der Methodenaufrufe

Person

get−namesayslap

Singer

sing

Rockstar

say

slap

Vorlaufige Version 443 c© 2007 Peter Thiemann

Page 60: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Zusammenfassung (Vererbung und Uberschreibung)

• Uberschreiben einer Methode kann Funktionalitat auf unvorhersehbare Weise

andern

• Ein Aufruf (send self mname ...) in einer Klasse A kann zum Aufruf von

mname in einer beliebigen Ober- oder Unterklasse B von A fuhren.

• Der Code einer Unterklasse B liegt zum Zeitpunkt des Erstellens von A meistens

noch nicht vor.

⇒ Der Effekt des Aufrufs einer uberschriebenen Methode ist fur den Programmierer

nicht vorhersehbar.

⇒ Bei Verwendung von Uberschreiben kann die Funktionsweise eines OO-Programms

nur durch Studium der gesamten Klassenhierarchie verstanden werden.

Vorlaufige Version 444 c© 2007 Peter Thiemann

Page 61: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

#16 (Uberschreiben von Methoden)

Vermeide das Uberschreiben von Methoden.

Vorlaufige Version 445 c© 2007 Peter Thiemann

Page 62: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

15.6 Mehrfachvererbung (Multiple Inheritance)

• Bisher:

– einfache Vererbung

– ein Objekt kann von genau einem Objekt erben

• Mogliche Erweiterung

– Mehrfachvererbung

– ein Objekt kan von mehreren Objekten erben

• MV nur von wenigen Sprachen unterstutzt (z.B. Eiffel, C++)

• Effiziente Implementierung von MV nicht einfach

• MV wird von manchen prinzipiell abgelehnt

Vorlaufige Version 446 c© 2007 Peter Thiemann

Page 63: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Beispiel: ein Poet

• Ein Poet ist ein eigenstandiges Objekt (keine Person)

• Ein Poet kann

– sprechen "say" und

– einen auswendig gelernten Text rezitieren "recite"

Vorlaufige Version 447 c© 2007 Peter Thiemann

Page 64: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Implementierung des Poet

; Dichter konstruieren

; make-poet : string -> (message -> method)

(define make-poet

(lambda (name)

(lambda (message)

(cond

((string=? message "say")

;; poet list(string) -> unspecified

(lambda (self text)

(write-list-newline (append text (list " and the sky is blue")))))

((string=? message "recite")

;; poet -> unspecified

(lambda (self)

(write-list-newline (list "the sky is blue"))))))))

Vorlaufige Version 448 c© 2007 Peter Thiemann

Page 65: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Ein Poet in Aktion

> (define james (make-poet "James"))

> (send james "say" (list "hi"))

hi and the sky is blue

> (send james "recite")

the sky is blue

Vorlaufige Version 449 c© 2007 Peter Thiemann

Page 66: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Erst Rockstar, dann Poet

• James ist eigentlich Rockstar

• Aber seine Texte konnen auch als Gedichte durchgehen

• Modellierung davon:

; james, der rockstar-poet

; james : message -> method

(define james

(let* ((name "James")

(rockstar (make-rockstar name))

(poet (make-poet name)))

(lambda (message)

(if ...

...

...))))

Vorlaufige Version 450 c© 2007 Peter Thiemann

Page 67: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Erweiterung des Dispatches

• Der Dispatch muss zwischen rockstar und poet als Empfanger unterscheiden.

• Falls rockstar die Nachricht versteht, dann soll rockstar sie verarbeiten.

• Falls rockstar die Nachricht nicht versteht, dann soll sie an poet weitergereicht

werden.

⇒ Erweitere den Dispatch-Code um Signalisierung, ob Nachricht verstanden

Vorlaufige Version 451 c© 2007 Peter Thiemann

Page 68: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Erweiterter Dispatch-Code fur person und poet

(define make-person

(lambda (name)

(let ((slaps 0))

(lambda (message)

(cond

((string=? message "get-name") ...)

((string=? message "say") ...)

((string=? message "slap") ...)

(else #f))))))

(define make-poet

(lambda (name)

(lambda (message)

(cond

((string=? message "say") ...)

((string=? message "recite") ...)

(else #f)))))

Vorlaufige Version 452 c© 2007 Peter Thiemann

Page 69: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Implementierung: Erst Rockstar, dann Poet

• James, der Rockstar, der auch Poet its

; james, der rockstar-poet

; james : message -> method

(define james

(let* ((name "James")

(rockstar (make-rockstar name))

(poet (make-poet name)))

(lambda (message)

(let ((rockstar-method (rockstar message)))

(if (equal? rockstar-method #f)

(poet message)

rockstar-method)))))

Vorlaufige Version 453 c© 2007 Peter Thiemann

Page 70: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Rockstar-Poet in Aktion

> (send james "say" (list"honey"))

honey, dude

> (send james "recite")

the sky is blue

> (send james "slap")

pain just makes me stronger, dude

> (send james "sing" (list "something"))

tra-la-la something, dude

Vorlaufige Version 454 c© 2007 Peter Thiemann

Page 71: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Alternative: Erst Poet, dann Rockstar

; henry, der poetische rockstar

; henry : message -> method

(define henry

(let* ((name "Henry")

(rockstar (make-rockstar name))

(poet (make-poet name)))

(lambda (message)

(let ((poet-method (poet message)))

(if (equal? poet-method #f)

(rockstar message)

poet-method)))))

Vorlaufige Version 455 c© 2007 Peter Thiemann

Page 72: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Poeten-Rockstar in Aktion

> (send henry "say" (list"honey"))

honey and the sky is blue

> (send henry "recite")

the sky is blue

> (send henry "slap")

pain just makes me stronger and the sky is blue

> (send henry "sing" (list "loo"))

tra-la-la loo and the sky is blue

Vorlaufige Version 456 c© 2007 Peter Thiemann

Page 73: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Mehrfachvererbung im Klassendiagramm

henryjames

Person

get−namesayslap

Singer

sing

Rockstar

say

slap

Poet

say

recite

Vorlaufige Version 457 c© 2007 Peter Thiemann

Page 74: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Zusammenfassung: Mehrfachvererbung

• Ein Objekt kann von mehreren Objekten erben

• Strategie fur Methodenauswahl wichtig

Fur Oberklassen, die die gleiche Nachricht verstehen, muss eine

Dispatch-Reihenfolge vereinbart werden

Bsp: zuerst Rockstar oder zuerst Poet?

• Zustandskomponenten?

• Zusammenwirken von Methoden noch komplexer

Vorlaufige Version 458 c© 2007 Peter Thiemann

Page 75: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

15.7 Abstraktion uber Klassen

• Ein Rockstar ist ein”cooler“ Sanger

•”Coolheit“ außert sich in einer Veranderung der say-Methode

• Warum ist”Coolheit“ auf Sanger beschrankt?

• Warum konnen nicht auch Poeten”cool“ sein?

• Ansatz: Abstrahiere uber die Oberklasse singer

Vorlaufige Version 459 c© 2007 Peter Thiemann

Page 76: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Rockstar wieder besucht

(define make-rockstar

(lambda (name)

(let ((singer (make-singer name)))

(lambda (message)

(cond

((string=? message "say")

;; Text sagen

;; rockstar list(string) -> unspecified

(lambda (self text)

(send singer "say" (append text (list ", dude")))))

...)))))

• Die Klasse Sanger wird durch ihre Konstruktorfunktion make-singer vertreten

• singer ist nur eine Variable, die umbenannt werden kann

Vorlaufige Version 460 c© 2007 Peter Thiemann

Page 77: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Ein Klassengenerator

; zu einer Klasse Coolness hinzufugen

; make-make-cool-someone :

; (string -> (message -> method)) -> (string -> (message -> method))

(define make-make-cool-someone

(lambda (make-super)

(lambda (name)

(let ((super (make-super name)))

(lambda (message)

(cond

((string=? message "say")

;; Text sagen

;; rockstar list(string) -> unspecified

(lambda (self text)

(send super "say" (append text (list ", dude")))))

...

(else (super message))))))))

Vorlaufige Version 461 c© 2007 Peter Thiemann

Page 78: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Alternative Konstruktion des Rockstar

; make-rockstar : string -> (message -> method)

(define make-rockstar

(make-make-cool-someone make-singer))

• funktioniert wie bisher . . .

; make-cool-poet : string -> (message -> method)

(define make-cool-poet

(make-make-cool-someone make-poet))

Beispiel:

> (define charles (make-cool-poet "Charles"))

> (send charles "say" (list "hello"))

hello, dude and the sky is blue

Vorlaufige Version 462 c© 2007 Peter Thiemann

Page 79: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

Zusammenfassung: Mixins

• Ein Mixin ist eine Klasse, die von ihrer Oberklasse abstrahiert ist

• Ein Mixin ist eine Funktion, die eine Klasse erweitert

• Die Eigenschaften werden in der Reihenfolge”probiert“, in der die Mixins

angewendet werden

#17 (Mixins)

Kapsele isolierte Eigenschaften von Klassen in Mixins

Vorlaufige Version 463 c© 2007 Peter Thiemann

Page 80: 15 Objektorientiertes Programmieren fileSpezi kation: Bankkonto als Objekt Ein Kontoobjekt ist eine Prozedur mit Vertrag account = number -> (number or #f) Die Prozedur hebt einen

15.8 Kontext: Objektorientierte Programmiersprachen

Hier OOPS

Einblick in die Implementierung Durch Compiler/System festgelegt

Definition und Verwendung durch Stan-

dardformen

Spezielle Syntax fur Methoden, Methoden-

aufrufe, Klassen, Vererbung usw.

(in vollem Scheme: Syntaxerweiterung

moglich)

?

Eigene Erweiterungen ausprobieren (als Compilerschreiber)

Einfach- oder Mehrfachvererbung Durch Compiler/System festgelegt

Klassen sind Werte Klassen sind spezielle Konstrukte

Abstraktion uber Klassen moglich Abstraktion uber Klassen nicht moglich

Vorlaufige Version 464 c© 2007 Peter Thiemann