Substitutionsprinzip

Werbung
Th. Letschert
OOP 2
6. Klassenentwurf II
© Th Letschert FH Gießen-Friedberg
Th. Letschert
OOP 2
Klassenentwurf II
- Substitutionsprinzip
Seite 2
Th. Letschert
OOP 2
Liskovs Substitutionsprinzip A:
syntaktische / statisch-semantische Substituierbarkeit
Seite 3
Substitutionsprinzip
Substitutionsprinzip (Liskov'sches Substitutionsprinzip)
Barbara Liskov
Werte des Subtyps dürfen überall dort verwendet werden,
wo Werte des Typs erlaubt sind.
T' < T => T'-Werte vertreten T-Werte
Kompatiblität von Typ und Subtyp
Zuweisung
an Typ-Variablen
Parameterübergabe
Ergebnisrückgabe
Funktionen
von Subtyp-Werten
von Subtyp-Argumenten
von Subtyp-Werten
an Typ-Parameter
aus Typ-
Subtyprelation in Java
Widening bei Klassentypen: Subklasse ~> Klasse
Widening bei primitiven Typen: primitiver Typ ~> weiterer primitiver Typ
Seite 4
Subtypen / Wozu
Subtypen machen Code flexibel
Code der mit dem Basistyp arbeitet, kommt mit allen Subtypen klar,
auch mit denen, die noch gar nicht existieren!
Katze
Stockente
Tier
Schleimiger
Alien
Sie landen erst 20017
auf der Erde.
Unser Code wird
auch sie bearbeiten!
for ( Tier t : tierStapel ) {
t.streicheln();
fuettern(t);
}
Seite 5
Subtypen und Vererbung
Substitutionsprinzip und Vererbung
Erweiterung einer Klasse zur Subklasse
Die Fähigkeiten / Attribute entsprechend des Typs
den Subtyp übernommen
Weitere Fähigkeiten / Attribute kommen hinzu
Substitutionsprinzip ist erfüllt
S
Sub ubsti
typ tuti
Typ -Werte onspr
in
-We
d
rte ürfen zip:
ver
tete imme
r
n.
werden in
Polymorphe Redefinitionen in der Subklasse
Fähigkeit des Typs wird im Subtyp modifiziert
Regeln der Redefinition müssen die Gültigkeit des
Substitutionsprinzip erzwingen
Su Erwe
bs
ite
gilt titutio rung
triv nsp :
iale rin
rwe zip
ise
Su Rede
gilt bstitu finiti
nic tion on:
ht a sp
uto rinzi
ma p
tisc
h
Ebenen der Gültigkeit des Substitutionsprinzips
Syntaktisch / statisch semantisch:
Keine Typfehler durch polymorphe Redefinition
Semantisch
Keine (inhaltlichen) Programmfehler durch Substitution
Seite 6
Substitutionsprinzip und polymorphe Redefinition
Unter welchen Bedingungen gilt das Substitutionsprinzip bei
polymorphen Redefinitionen?
Ist Java streng genug: Sind die Regeln von Java scharf genug,
um seine Gültigkeit zu garantieren ?
Ist Java zu streng: Gibt es (im Prinzip) gültige Redefinitionen,
die von Java ausgeschlossen werden?
Seite 7
Substitutionsprinzip und polymorphe Redefinition
Java Redefinitionsregel 1:
Die Parameter der neuen Methode müssen in Typ und Zahl mit
denen der ersetzten Methode übereinstimmen.
Regel hinreichend ? (oder nicht streng genug)
Regel notwendig ? (oder zu streng)
Seite 8
Substitutionsprinzip und polymorphe Redefinition
Java Redefinitionsregel 1:
Die Parameter der neuen Methode müssen in Typ und Zahl mit
denen der ersetzten Methode übereinstimmen.
Regel hinreichend !
aber zu streng:
Redefinitionsregel 1:
Kontravariante Modifikationen im Parametertyp sind kompatibel mit dem
Substitutionsprinzip.
Seite 9
Substitutionsprinzip und polymorphe Redefinition
Redefinitionsregel 1 (Kontravarianz in den Parametern):
Kontravariante Modifikationen im Parametertyp sind kompatibel mit dem
Substitutionsprinzip.
Beim Fressen kann ein Wildhund einen
Hund vertreten!
Hund
Fleisch
name: String
frisst(Chappi)
Java: Entwurf OK, wird aber von Java so
nicht umgesetzt.
UML: UML ist nicht so exakt definiert,
dass das Diagramm eindeutig interpretiert
werden kann. (Nimm es als gemaltes
Java!)
WildHund
name: String
frisst(Fleisch)
Chappi
Substitutionsprinzip:
Wildhund kommt mit Chappi als
Parameter seiner frisst-Methode klar
Chappi
Kontext bietet Chappi
Hunde aller Art leben
gut in diesem Kontext
Seite 10
Substitutionsprinzip und polymorphe Redefinition
Java Redefinitionsregel 2:
Der Ergebnistyp der neuen Methode muss gleich dem Ergebnistyp
der ersetzten Methode sein oder diesen kovariant verändern
Regel hinreichend ? (oder nicht streng genug)
Regel notwendig ? (oder zu streng)
Seite 11
Substitutionsprinzip und polymorphe Redefinition
Java Redefinitionsregel 2:
Der Ergebnistyp der neuen Methode muss gleich dem Ergebnistyp
der ersetzten Methode sein oder diesen kovariant verändern
Regel notwendig und hinreichend
Redefinitionsregel 2:
Kovariante Modifikationen im Ergebnistyp sind kompatibel mit dem
Substitutionsprinzip.
Seite 12
Substitutionsprinzip und polymorphe Redefinition
Redefinitionsregel 2 (Kovarianz im Ergebnis):
Kontravariante Modifikationen im Parametertyp sind kompatibel mit dem
Substitutionsprinzip.
Bauer
Bei der Produktion kann ein Bergbauer einen
Bauer vertreten!
Futter
produziert(): Futter
Java: Entwurf OK, und wird so umgesetzt.
UML: OK
Gras
BergBauer
produziert (): Gras
Futter
OK
Kontext
erwartet
Futter
Bauer
Gras
BergBauer
Seite 13
OK
Substitutionsprinzip / Syntaktisch
Regel über die Signatur der substituierten
(redefinierten) Methoden:
1. Kontravarianz in den Parametertypen
2. Kovarianz im Ergebnistyp
Signatur einer Methode:
Name
+ Zahl/Typen der Parameter
+ Typ des Ergebnisses
Syntaktische / statisch-semantische
Regel
Seite 14
Substitutionsprinzip und polymorphe Redefinition
Beispiel
Katze
frisst(Maus)
KleinTier
Genaue Bedeutung:
was genau sagt das Diagramm aus
WildKatze
Maus
Konzeptionell OK:
handelt es sich um einen korrekten
OO-Entwurf, wird also
insbesondere das
Substitutionsprinzip respektiert ?
frisst(KleinTier)
In Java (Falls OK):
Wie wird der Entwurf, falls OK, in
Java umgesetzt, ist insbesondere
eine direkte Umsetzung in das
Java.Typsystem möglich,
oder muss auf Laufzeit-Prüfungen
ausgeichen werden ?
Seite 15
Substitutionsprinzip und polymorphe Redefinition
Beispiel
Katze
fängt():Maus
KleinTier
Genaue Bedeutung ?
Konzeptuell OK ?
In Java (Falls OK)?
WildKatze
Maus
fängt():KleinTier
Seite 16
Substitutionsprinzip und polymorphe Redefinition
Beispiel
Arzt
behandelt(Patient)
HNOArzt
AugenArzt
behandelt(HalsPatient)
behandelt(AugenPatient)
Patient
HalsPatient
AugenPatient
Seite 17
Assoziationen ?
Genaue Bedeutung ?
Konzeptuell OK ?
In Java (Falls OK)?
Th. Letschert
OOP 2
Liskovs Substitutionsprinzip B:
Semantische Substituierbarkeit
Seite 18
Substitutionsprinzip / Semantisch
Regel über die Spezifikation der substituierten
(redefinierten) Methoden:
1. Keine Verschärfung der Vorbedingung
2. Keine Abschwächung der Nachbedingung
Semantische
Regel
Kovarianz und Kontravarianz
auf semantischer Ebene
Spezifikation einer Methode
Vorbedingung
Beschreibung der Voraussetzung der Methode:
Bedingung unter denen eine Methode ihr korrektes Verhalten
garantiert.
Nachbedingung
Beschreibung der Wirkung der Methode:
Bedingung, die nach ihrer Ausführung gilt.
Seite 19
Substitutionsprinzip / Semantisch: Beispiel
Beispiel / Vorbedingung
Ein Stack ist ein Speicher mit LIFO-Verhalten
Stack
Ein BoundedStack ist ein Stack mit begrenztem
Fassungsvermögen
push(int)
pop():int
BoundedStack
push(int)
pop():int
Seite 20
Substitutionsprinzip / Semantisch: Beispiel
Beispiel / Vorbedingung
Ein Stack ist ein Speicher mit LIFO-Verhalten
Stack
Ein BoundedStack ist ein Stack mit begrenztem
Fassungsvermögen
push(int x)
pop():int
pre: post: x liegt auf dem Stapel
BoundedStack
push(int x)
pop():int
pre: darf nicht voll sein
post: x liegt auf dem Stapel
Seite 21
Substitutionsprinzip / Semantisch: Beispiel
Beispiel / Vorbedingung
Ein Stack ist ein Speicher mit LIFO-Verhalten
Stack
Ein BoundedStack ist ein Stack mit begrenztem
Fassungsvermögen
push(int x)
pop():int
pre: post: x liegt auf dem Stapel
Entwurfsfehler:
Verstoß gegen das
Substitutionsprinzip
ein BoundedStack kann nicht als
Vertreter eines Stacks agieren!
BoundedStack
push(int x)
pop():int
pre: darf nicht voll sein
post: x liegt auf dem Stapel
Seite 22
Substitutionsprinzip / Semantisch: Beispiel
Beispiel / Nachbedingung
Sparvertrag
auszahlen():Geld
pre: monatlich eingezahlt
post: returns kontoStand
+ 2.5 % Zinsen
DagobertSparen
auszahlen():Geld
pre: wöchentlich eingezahlt
post: returns kontoStand
+ 0.5 % Zinsen
Ein Sparvertrag wird bei monaticher Einzahlung mit 2,5% ausgezahlt
DagobertSparen, ein Sparvertrag bei der Dagobert-Bank, ist ein
spezieller Sparvertrag, der nur 0,5% Zinsen bietet.
Seite 23
Substitutionsprinzip / Semantisch: Beispiel
Beispiel / Nachbedingung
Sparvertrag
auszahlen():Geld
pre: monatlich eingezahlt
post: returns kontoStand
+ 2.5 % Zinsen
Niemand wird ein DagobertSparen
als Vertreter eines Sparvertrags
akzeptieren!
DagobertSparen
auszahlen():Geld
Entwurfsfehler:
Verstoß gegen das
Substitutionsprinzip
pre: wöchentlich eingezahlt
post: returns kontoStand
+ 0.5 % Zinsen
Ein Sparvertrag wird bei monaticher Einzahlung mit 2,5% ausgezahlt
DagobertSparen, ein Sparvertrag bei der Dagobert-Bank, ist ein
spezieller Sparvertrag, der nur 0,5% Zinsen bietet.
Seite 24
Substitutionsprinzip / Semantisch: Beispiel
Beispiel
Sparvertrag
auszahlen():Geld
pre: monatlich eingezahlt
post: returns kontoStand
+ 2.5 % Zinsen
pre: jährlich eingezahlt
post: returns kontoStand
+ 5 % Zinsen
SparvertragS
auszahlen():Geld
OK ?
Seite 25
Substitutionsprinzip / Semantisch
Semantische
Regel
Übertragung des Substitutionsprinzips auf
Spezifikationen
Vorbedingung
Die Vorbedingung einer redefinierten Methode muss
gleich oder oder schwächer sein.
Nachbedingung
Die Nachbedingung einer redefinierten Methode muss
gleich oder stärker sein.
Sparvertrag
auszahlen():Geld
SparvertragS
auszahlen():Geld
pre: monatlich eingezahlt
post: returns kontoStand
+ 2.5 % Zinsen
pre: jährlich eingezahlt
post: returns kontoStand
+ 5 % Zinsen
OK:
Ableitung schwächt Forderung ab
und
erhöht Leistung.
Seite 26
Der Ersatz darf von
seinem Verwender
nicht mehr verlangen!
Der Ersatz darf für
seinen Verwender
nicht weniger leisten!
Su Subs
Vo btype titut
rbe
i
din n hab onsp
Na gung en sc rinzip
chb en
h
edi und wäch :
ngu sc ere
nge här
fere
n
Substitutionsprinzip / Beispiel
Beispiel
Ein Rechteck hat eine Breite und eine Höhe,
man kann es zeichnen,
man kann Breite und Höhe ändern
Ein Quadrat ist eine besondere Art von Rechteck:
Breite und Höhe sind immer gleich
Menge
aller
Quadrate
Menge aller
Rechtecke
mengentheortische Sicht
der
Vererbung / SubtypEigenschaft
Rechteck
breite: int
hoehe: int
setBreite(int):void
setHoehe(int):void
zeichne():void
inv: breite = hoehe
Quadrat
Invariante:
Bedingung an den Zustand der
Objekte der Klasse.
Seite 27
OK ?
Substitutionsprinzip / Beispiel
Beispiel
Ein Rechteck hat eine Breite und eine Höhe,
man kann es zeichnen,
man kann Breite und Höhe ändern
Ein Quadrat ist eine besondere Art von Rechteck:
Breite und Höhe sind immer gleich
Menge
aller
Quadrate
stimmt nicht
diese Quadrate
sind keine
Rechtecke
Menge aller
Rechtecke
mengentheortische Sicht der
Vererbung / Subtyp-Eigenschaft
Rechteck
breite: int
hoehe: int
setBreite(int):void
setHoehe(int):void
zeichne():void
inv: breite = hoehe
Quadrat
Seite 28
Verstoß gegen das
Substitutuionsprinzip: Invariante
kann verletzt werden.
setHoehe / setBreite
bei Quadrat ?
Die Quadrate können nicht überall an
die Stelle von Rechtecken treten.
Substitutionsprinzip / Beispiel
Beispiel
Ein Rechteck hat eine Breite und eine Höhe,
man kann es zeichnen,
Ein Quadrat ist eine besondere Art von Rechteck:
Breite und Höhe sind immer gleich
Menge
aller
Quadrate
Menge aller
Rechtecke
mengentheortische Sicht
der
Vererbung / SubtypEigenschaft
Rechteck
breite: int
hoehe: int
zeichne():void
inv: breite = hoehe
Quadrat
OK ?
Seite 29
Substitutionsprinzip / Beispiel
Beispiel
Ein Rechteck hat eine Breite und eine Höhe,
man kann es zeichnen,
Ein Quadrat ist eine besondere Art von Rechteck:
Breite und Höhe sind immer gleich
OK:
Objekte werden als Werte
(unveränderlich) betrachtet
~ mathematische Sicht auf
Quadrate und Rechtecke
Menge
aller
Quadrate
Menge aller
Rechtecke
mengentheortische Sicht
der
Vererbung / SubtypEigenschaft
Rechteck
breite: int
hoehe: int
zeichne():void
inv: breite = hoehe
Quadrat
Substitutionsprinzip nicht verletzt:
Invariante der Ableitung kann
kann bei Gebrauch als Basis-Objekt
nicht verletzt werden.
OK !
Wertartige Objekte und Objekte
mit Zustand sind im Entwurf zu
unterscheiden!
Seite 30
Substitutionsprinzip / Beispiel
Beispiel
Rechteck
breite: int
hoehe: int
setSize(x:int,y: int):void
zeichne():void
Quadrat
pre: x>=0, y>=0
OK ?
pre: x>=0, y>=0, x=y
setSize(x:int,y: int):void
Ein Quadrat ist eine Art von Rechteck:
Eins bei dem man die Grösse in x- und in yRichtung immer gleich setzt.
Seite 31
Substitutionsprinzip / Beispiel
Beispiel
Verstoß gegen das Substitutionsprinzip:
Verschärfung der Vorbedingung
nicht erlaubt!
Rechteck
breite: int
hoehe: int
setSize(x:int,y: int):void
zeichne():void
Quadrat
pre: x>=0, y>=0
pre: x>=0, y>=0, x=y
setSize(x:int,y: int):void
Ein Quadrat ist eine Art von Rechteck:
Eins bei dem man die Grösse in x- und in yRichtung immer gleich setzt.
Seite 32
Substitutionsprinzip / Beispiel
Beispiel
Rechteck
breite: int
hoehe: int
setSize(x:int,y: int):void
zeichne():void
Quadrat
pre: x>=0, y>=0
OK ?
pre: x>=0, y>=0
throws BadSize if not x=y
setSize(x:int,y: int):void
Na gut, dann Exception statt
Vorbedingung.
Seite 33
Substitutionsprinzip / Beispiel
Beispiel
Rechteck
breite: int
hoehe: int
setSize(x:int,y: int):void
zeichne():void
Quadrat
pre: x>=0, y>=0
Exceptions dürfen
nicht hinzugefügt
werden!
pre: x>=0, y>=0
throws BadSize if not x=y
setSize(x:int,y: int):void
Seite 34
Substitutionsprinzip / Beispiel
Beispiel
Rechteck
breite: int
hoehe: int
setSize(x:int,y: int):void
zeichne():void
Rechteck
breite: int
hoehe: int
setSize(x:int,y: int):void
throw BadSize
zeichne():void
Quadrat
Quadrat
setSize(x:int,y: int):void
throw BadSize
setSize(x:int,y: int):void
throw BadSize
nicht OK
OK
Seite 35
Substitutionsprinzip / Semantisch
Regel über die Spezifikation der substituierten
(redefinierten) Methoden:
1. Keine Verschärfung der Vorbedingung
2. Keine Abschwächung der Nachbedingung
3. Keine Verletzung der Invariante
4. Keine zusätzlichen Exceptions
Spezifikation einer Methode
Vorbedingung
Beschreibung der Voraussetzung der Methode:
Bedingung unter denen eine Methode ihr korrektes Verhalten
garantiert.
Nachbedingung
Beschreibung der Wirkung der Methode:
Bedingung, die nach ihrer Ausführung gilt.
Invariante
Beschreibung der Bedingung die an den Zustand der Objekte gestellt
wird:
Bedingung, die nach vor/nach jeder Ausführung einer Methode gilt.
Seite 36
Substitutionsprinzip und polymorphe Redefinition
Beispiel
pre: ......................
post: Patient gesund
Arzt
fach: Fach
behandelt(Patient)
HNOArzt
AugenArzt
behandelt(HalsPatient)
behandelt(AugenPatient)
Patient
krankheit: Krankheit
inv: ......................
inv: ......................
HalsPatient
AugenPatient
Seite 37
Vorbedingung ?
Invarianten ?
Klassen-Assoziationen
Genaue Bedeutung ?
Konzeptuell OK ?
In Java (Falls OK)?
Substitutionsprinzip und polymorphe Redefinition
Beispiel
Arzt
fach: Fach
behandelt(Patient)
Krankenhaus
aufnehmen(Patient)
*
HNOArzt
AugenArzt
behandelt(HalsPatient)
behandelt(AugenPatient)
Patient
krankheit: Krankheit
HalsPatient
AugenPatient
Seite 38
Ein Krankenhaus nimmt einen
Patienten auf und lässt ihn durch
einen seiner Ärzte mit der richtigen
Fachrichtung behandeln.
In Java ?!
Substitutionsprinzip und polymorphe Redefinition
Beispiel
Arzt
behandelt(Patient)
Krankenhaus
aufnehmen(Patient)
*
HNOArzt
AugenArzt
behandelt(HalsPatient)
behandelt(AugenPatient)
Ein Krankenhaus nimmt einen
Patienten auf und lässt ihn durch
einen seiner Ärzte mit der richtigen
Fachrichtung behandeln.
Unterschied zum Beispiel vorher?
Patient
heilen()
Vorbedingungen / Invarianten ?
In Java ?!
HalsPatient
heilen()
AugenPatient
heilen()
Seite 39
Substitutionsprinzip und polymorphe Redefinition
Beispiel
Arzt
behandelt(Patient)
throws InkompetentEx
Krankenhaus
aufnehmen(Patient)
*
HNOArzt
AugenArzt
behandelt(HalsPatient)
throws InkompetentEx
behandelt(AugenPatient)
throws InkompetentEx
Ein Krankenhaus nimmt einen
Patienten auf und lässt ihn durch
einen seiner Ärzte mit der richtigen
Fachrichtung behandeln.
Unterschied zum Beispiel vorher?
Patient
heilen()
Vorbedingungen / Invarianten ?
In Java ?!
HalsPatient
heilen()
AugenPatient
heilen()
Seite 40
Substitutionsprinzip und polymorphe Redefinition
Beispiel
Arzt
behandelt(Patient)
throws InkompetentEx
Krankenhaus
aufnehmen(Patient)
*
Bitte erweitern um:
HNOArzt
AugenArzt
behandelt(HalsPatient)
throws InkompetentEx
behandelt(AugenPatient)
throws InkompetentEx
Patient
heilen()
HalsPatient
heilen()
AugenPatient
heilen()
Seite 41
Ein Krankenhaus nimmt Patienten auf
- und lässt sie durch durch seinen
Aufnahmearzt untersuchen,
- der heilt sie selbst wenn es sich um
SchnupfenPatient handelt, sonst
verweist er sie an einen der Fachärzte,
der dann die Behandlung übernimmt.
- Der Aufnahmearzt ist ein Arzt der
Fachrichtung AllgemeinMedizin.
UML-Modell ?
Klassen / abstr. Klassen / Schnittstellen
Assoziationen ?
Vor-/Nachbedingungen ?
Invarianten ?
In Java ?
Liskov'sches Substitutionsprinzip / Zusammenfassung
Substitutionsprinzip:
Syntaktisch / statisch semantisch
1. Kontravarianz in den Parametertypen
2. Kovarianz im Ergebnistyp
Semantisch
1. Keine Verschärfung der Vorbedingung
2. Keine Abschwächung der Nachbedingung
3. Keine Verletzung der Invariante
4. Keine zusätzlichen Exceptions
Einsatz:
Richtlinie zum Klassenentwurf
Seite 42
Herunterladen