4. Klassenentwurf I

Werbung
Th. Letschert
OOP 2
4. Klassenentwurf I
© Th Letschert FH Gießen-Friedberg
Th. Letschert
OOP 2
Klassenentwurf
- Besondere Methoden
- Vererbungskonzepte: Klasse, Abstrakte Basisklasse, Schnittstelle
- Dynamische Typprüfungen
Seite 2
Th. Letschert
OOP 2
Besondere Methoden:
- toString
- clone
- equals
- hashCode
Seite 3
toString
toString
ist in Klasse Object als public definiert
wird von allen Klassen geerbt
sollte bei Bedarf sinnvoll redefiniert werden
Textuelle Darstellung des Objekts
Casts:
Jedes Objekt kann in einen String konvertiert werden
dabei wird die toString Methode genutzt
Seite 4
clone
clone
ist in Klasse Object als protected definiert
erzeugt Kopie (Klon) des Objekts
wird von allen Klassen geerbt
kann verwendet werden, wenn die Klasse Cloneable implementiert
sonst: java.lang.CloneNotSupportedException
Schnittstelle implementieren: Hinweis, dass Klonen erlaubt ist
Flache Kopie als Standard-Semantik
sollte bei Bedarf sinnvoll redefiniert werden mit:
x.clone() != x
x.clone().equals(x)
Seite 5
clone: Beispiel (1)
Base enthält:
- xb : modifizierbar / primitiv
- sb: nicht modifizierbar / Klassentyp
- arrayb : modifizierbar / Klassentyp
class Base implements Cloneable {
int
xb;
String
sb;
String[] arrayb = new String[1];
Base(String name) {
sb = name;
arrayb[0] = name;
}
}
public Object clone () {
Base b = null;
try {
b = (Base) super.clone();
} catch (CloneNotSupportedException e) {}
b.arrayb = arrayb.clone();
return b;
}
Seite 6
super.clone = Object.clone
kopiert Bit für Bit
- xb, OK: Wert in Variable
- sb, OK: Wert nicht modifizierbar
- arrayb: muss gesondert kopiert
werden,
Felder von Java definiert,
haben wohl korrekte
clone-Methode
try-catch: überflüssig, aber
der Compiler will es so!
clone: Beispiel (2)
class Derived extends Base implements Cloneable {
int
xd;
String
sd;
String[] arrayd = new String[1];
Derived (String name) {
super(name+"-B");
sd = name;
arrayd[0] = name;
}
public Object clone () {
Derived d = (Derived) super.clone();
d.arrayd = arrayd.clone();
return d;
}
}
Seite 7
Abgeleitete Klasse
Basisanteil und primitive
Komponenten werden von
super.clone korrekt geklont, für die
nicht-primitiven / veränderbaren
Erweiterungen sorge selbst!
equals / hashCode
equals
ist in Klasse Object als public definiert
wird von allen Klassen geerbt
sollte sinnvoll redefiniert werden
reflexiv, symetrisch, transitive Interpretation von Gleichheit
equals(null) => false
hashCode
ist in Klasse Object als public definiert
wird von allen Klassen geerbt
sollte sinnvoll redefiniert werden
wenn equals redefiniert wird
und die Objekte eventuell in einer Hashtabelle gespeichert werden
gleiche Objekte sollten den gleichen Hashcode liefern
Seite 8
Th. Letschert
OOP 2
Vererbungskonzepte:
Klasse, Abstrakte Basisklasse, Schnittstelle
Seite 9
Vererbungskonzepte
Vererbung:
- Zwei Aspekte:
Weitergabe von Implementierungen / - von Verhalten
- Zwei Vorgehensweisen im Entwurf der Klassen:
Generalisieren / Spezialisieren
- Drei Arten von Klassen:
Klasse / abstrakte Klasse / Schnittstelle
Seite 10
Vererbung / 2 Aspekte: Gemeinsamer Code / Gemeinsames Verhalten
Vererbung: Aspekte
Implementierungs
-vererbung
Person
name: string
Einsatz 1 : gemeinsamer Code
Klassen nutzen (gemeinsam) die
Implementierung einer Basisklasse
„interne Sicht“ (Implementierungsvererbung):
Organisation der Klassen-Definitionen
nach dem Prinzip „Ist-eine-Art-von“
Einsatz 2: Gemeinsames Verhalten
Klassen haben Gemeinsamkeiten im
Verhalten: sie können unterschiedslos
verwendet werden.
„externe Sicht“ (Schnittstellenvererbung,
Substituierbarkeit):
Benutzung der Klassen / Objekte
Leitlinie: „Verhält-sich-so-wie“
Schnittstellenvererbung
Seite 11
Student
Dozent
Personen, Studenten und
Dozenten haben einen Namen
Tontraeger
abspiele(): void
<<realize>>
CD
abspiele():void
<<realize>>
MC
abspiele():void
CDs und Mcs können abgespielt
werden.
Vererbung / 2 Vorgehensweisen: Generalisieren / Spezialisieren
Spezialisieren:
- Wiederverwendung: die neue (abgeleitete) Klasse nutzt Code der
der alten (Basis-) Klasse
- Substituierbarkeit: die neue Klasse bewahrt Fähigkeiten der alten
(Basis-) Klasse
CD
CD
titel: String
spieldauer: int
titel: String
spieldauer: int
abspielen():void
abspielen():void
PopCD
Redefiniert
vorher
abspielen():void
shuffle():void
nachher
Seite 12
titel,
spieldauer
übernommen
Erweitert
Generalisieren / Spezialisieren
Wiederverwendung durch Generalisieren:
die neue (Basis-) Klasse entsteht durch
- Wiederverwendung: Ausfaktorisieren gemeinsamer Attribute / Methoden
abstrakte
- Substituierbarkeit: Abstraktion gemeinsamer Fähigkeiten
Klasse
Tonträger
ausfaktorisiert
CD
MC
titel: String
nTracks: int
titel: String
laenge: int
abspielen():void
abspielen():void
abstrahiert
vorher
titel: String
abspielen():void
CD
MC
nTracks: int
laenge: int
abspielen():void
abspielen():void
nachher
Seite 13
Abstrakte Klasse
Abstrakte Klasse
Klasse die nicht instanziert werden kann (von der es keine Exemplare gibt)
beschreibt
gemeinsamen Code und
gemeinsame Fähigkeiten der Klasse und ihrer Ableitungen
Schrägschrift!
public abstract class TonTraeger {
protected String titel;
public abstract void abspielen();
....
}
abstrakte
Klasse
Aspekt: Code-Wiederverwendung
Tonträger
titel: String
abspielen():void
abstrakte
Methode
Schrägschrift!
Aspekt: Verhaltensgemeinsamkeit
Seite 14
Abstrakte Klasse
Abstrakte Methode
Methode ohne Implementierung
Schnittstellen-Vererbung: beschreibt prinzipielle Fähigkeiten (Können) aller
Objekte in abgeleiteten Klassen
Tonträger
titel: String
abspielen():void
abstrakte
Methode
Figur
Die verschiedenen Figuren werden auf verschiedene
Art gezeichnet.
Es macht keinen Sinn hier, in der Klasse Figur, eine
Implementierung der Zeichenroutine anzugeben.
xPos:int
yPos:int
draw():void
Die verschiedenen Tonträger werden auf
verschiedene Art abgespielt.
Es macht keinen Sinn hier, in der Klasse Tonträger,
irgendeine Implementierung anzugeben.
abstrakte
Methode
Seite 15
Abstrakte Klasse
Abstrakte Klasse
Schnittstellenvererbung
und Implementierungsvererbung
wird mit den Schlüsselwort abstrakt definiert
abstract class AbsClass { ... }
darf abstrakte Methoden besitzen: Methode ohne
Körper
abstract void absMethod(int x, int y);
Objekterzeuger:
Mechanismus zur ObjektErzeugung
Wiederverwendung: Basis
für die Definition von
Erweiterungen
Typ: Typ der Objekte
Dient als Basisklasse für Ableitungen, nicht zur
Erzeugung von Objekten
AbsClass a = new AbsClass();
Verkörpert Konzept (Typ) von Objekten
niemand ist nur Mensch, ohne gleichzeitig auch Frau oder
Mann zu sein
Mensch m = new Frau(''Müller''); // OK
Mensch m = new Mensch(''Maier''); // nicht OK
Seite 16
Klasse
abstrakte Klasse
Interface : Spezialkonstrukt für reine Schnittstellenvererbung
Interface
Klasse die nicht instanziert werden kann (von der es keine Exemplare gibt)
Ein Zahlungsmittel ist
beschreibt nur
etwas mit dem man
Rechnungen
gemeinsame Fähigkeiten ihrer Ableitungen
bezahlen kann!
interface Zahlungsmittel {
public void bezahlen(Rechnung rechnung);
}
<<Interface>>
Zahlungsmittel
bezahlen(Rechnung)
:void
<<realize>>
<<realize>>
Ueberweisung
Kreditkarte
kontoNr: int
besitzer: String
kartenNr: int
besitzer: String
bezahlen(Rechnung)
:void
bezahlen(Rechnung)
:void
class Kreditkarte implements Zahlungsmittel {
private String besitzer;
private int kartenNr;
public Kreditkarte(String besitzer, int nummer) {
this.besitzer = besitzer;
this.kartenNr = nummer;
}
public void bezahlen(Rechnung rechnung) {
System.out.println("Rechnung mit Karte bezahlt !");
}
}
Seite 17
Interface
Interface
Schnittstellenvererbung
wird mit den Schlüsselwort interface definiert
interface class AnInterface { ... }
Objekterzeuger:
Mechanismus zur ObjektErzeugung
Wiederverwendung: Basis
für die Definition von
Erweiterungen
enthält nur abstrakte Methoden
void absMethod(int x, int y);
Verkörpert reinen Typ
Typ: Typ der Objekte
etwas das eine Schnittstelle erfüllt hat bestimmte
Fähigkeiten, sonst brauchen keine Gemeinsamkeiten zu
bestehen
Zahlungsmittel m1 = new EuroMuenze(''5''); Zahlungsmittel m2 = new BankBuergschaft(...);
bezahlen(rechnung, m1);
bezahlen(rechnung, m2); Seite 18
Klasse
abstrakte Klasse
Interface
Zusammenfassung: Varianten von Klassen
Klasse : Objekt-Erzeugung / Code-Wiederverwendung / Typ
Mechanismus zur Objekterzeugung
Wiederverwendung bei Ableitung: Gemeinsame Attribute und Methoden
Typ, Basistyp für abgeleitete Klassen
abstrakte Klasse: Code-Wiederverwendung / Typ
Wiederverwendung bei Ableitung: Gemeinsame Attribute und Methoden
Typ, Basistyp für abgeleitete Klassen
Interface : Typ
Typ, Basistyp für abgeleitete Klassen
Seite 19
UML: Import-Schnittstellen und Export-Schnittstellen
Hund ist die gemeinsame Schnittstelle von
Boxer, Bernhardiner und Dogge ist ein Typ, verkörpert die
Fähigkeit bellen zu können
Zwinger benutzt die Hunde-Schnittstelle:
In einen Zwinger kann man alles einsperren, das
bellen kann!
Zwinger
Hund
Import-Schnittstelle
Zwinger
Boxer
<<use>>
<<realize>>
Hund
Hund
<<realize>>
gibLaut():void
Export-Schnittstelle
gibLaut():void
UML :
<<realize>>
Boxer
Dogge
Bernhardiner
gibLaut():void
gibLaut():void
gibLaut():void
Seite 20
Import-Schnittstelle: von einer
Klasse benutzte Schnittstelle
Export-Schnittstelle: von einer
Klasse realisierte / implem.
Schnittstelle
Import-Schnittstellen und Export-Schnittstellen
Bernhardiner
Hund
gibLaut():void
gibLaut():void
Dogge
Hund
gibLaut():void
Boxer
Hund
Wozu Import- und Export-Schnittstellen in UML?
Hund
gibLaut():void
Umsetzung in Java?
Warum kein entsprechendes Sprachkonstrukt?
Zwinger
Hund
Seite 21
Th. Letschert
OOP 2
Beispiele A
Seite 22
Klassenentwurf: Beispiel 1
List
PriorityQueue
PriorityQueue
List
Eine Prioritätswarteschlange
ist eine besondere Art von
Liste: eine immer nach
Priorität sortierte Liste.
Eine Prioritätswarteschlange
enthält eine Liste:
die sortierte Liste
ihrer Elemente.
Seite 23
Gut,
Schlecht,
Egal
?
Klassenentwurf: Beispiel 1
ist-ein ist im Zweifel schlechter als hat-ein !
List
PriorityQueue
PriorityQueue
List
Eine Prioritätswarteschlange
ist eine besondere Art von
Liste: eine immer nach
Priorität sortierte Liste.
Eine Prioritätswarteschlange
enthält eine Liste:
die sortierte Liste
ihrer Elemente.
Pfui
OK
Seite 24
Die
Implementierung
einer anderen
Klasse sollte man
durch eine
benutzt-Beziehung
statt durch eine
erbt-Beziehung zur
Verfügung stellen!
Klassenentwurf: Beispiel 2
OK ?
Tier
Haustier
Hund
WildHund
Katze
HausHund
HausKatze
Seite 25
WildKatze
Klassenentwurf: Beispiel 2
Tier
Hund
WildHund
Haustier
HausHund
Katze
HausKatze
WildKatze
Mehrfachvererbung ohne, dass alle außer einer Basisklasse Schnittstellen sind:
Entwurf prüfen ! Möglicherweise fehlerhaft! Java mag das nicht!
Unterscheide Klassen- und Schnittstellenvererbung !
Welche Klassen sind konkret, abstrakt, Schnittstellen?
Seite 26
Klassenentwurf: Beispiele 2
„Wesens“-Merkmale: Klassen-/Implementierungs-Vererbung
•
•
•
•
Tier
Hund
Katze
Haustier
•
•
•
•
Wildkatze
Wildhund
Haushund
Hauskatze
konkret
abstrakt
Verhaltens-Merkmale: Schnittstellenvererbung
Seite 27
Klassenentwurf: Beispiel 2
abstrakt
Tier
konkret
Schnittstelle
<<interface>>
Wild
Hund
<<realize>>
<<realize>>
WildHund
Katze
<<interface>>
Zahm
WildKatze
<<realize>>
<<realize>>
HausKatze
HausHund
Seite 28
Klassenentwurf: Beispiel 3
Haustiere
sind zahme Tiere
Tier
Zahm
Haustier
Hauskatze,
Haushund ?
Seite 29
Klassenentwurf: Beispiel 3
Haustiere
sind zahme Tiere
Hunde sind Tiere
Haushunde sind
Hunde und
Haustiere
Tier
Zahm und ein
Tier sein
Zahm
Haustier
Hund
Ein Hund sein
HausHund
Auf tierische Art
zahm
und ein Hund
sein
OK ?
Seite 30
Klassenentwurf: Beispiel 3
Das Konzept Haustier ist
sehr zweifelhaft !
Wozu „Haustier“?
Was soll es ausdrücken? Definiert
es ein Verhaltenskonzept? Definiert
es eine Basisklasse?
Auf tierische Art
zahm sein:
Was soll das
sein?
Was außer
Verwirrung
bringt das
Haustier?
Tier
Zahm
Haustier
Hund
Wahrscheinlich Unsinn !
Ein Hund sein
HausHund
Konzepte nicht einfach aus der Realität
übernehmen!
Die Realität ist komplex. Ihre Konzepte
drücken meist mehr und Komplexeres
aus, als in der SW gebraucht wird.
Auf tierische Art
zahm
und ein Hund
sein
Seite 31
Klassenentwurf: Beispiel 4
Gesucht: Klassenentwurf für
Player
CDPlayer,
DVDPlayer,
ComboDrive
Idee
Player:
CDPlayer:
spielt digitale Medien
spielt CDs
sind digitale Medien
DVDPlayer:
spielt DVDs
ComboDrive:
spielt das was man ihm gibt
Seite 32
CDs und DVDs
Klassenentwurf: Beispiel 4a
public class ComboDrive {
class DigitMedium {}
class CD extends DigitMedium {}
class DVD extends DigitMedium {}
public void play(DVD m) {
dvdPlayer.play(m);
}
public class Player {
public void play(CD m) {
cdPlayer.play(m);
}
public void play(DigitMedium m) {..}
}
public class CDPlayer extends Player {
private CDPlayer cdPlayer;
private DVDPlayer dvdPlayer;
public void play(CD cd) {..}
}
}
public class DVDPlayer extends Player {
public void play(DVD dvd) { .. }
}
OK ?
UML Diagramm ?
Seite 33
Klassenentwurf: Beispiel 4a
public class ComboDrive {
class DigitMedium {}
class CD extends DigitMedium {}
class DVD extends DigitMedium {}
public void play(DVD m) {
dvdPlayer.play(m);
}
public class Player {
public void play(DigitMedium m) {..}
public void play(CD m) {
cdPlayer.play(m);
}
}
public class CDPlayer extends Player {
private CDPlayer cdPlayer;
private DVDPlayer dvdPlayer;
public void play(CD cd) {..}
}
}
public class DVDPlayer extends Player {
public void play(DVD dvd) { .. }
}
Nicht OK,
keine Redefinition von play
Player als Klasse ?
Seite 34
Klassenentwurf: Beispiel 4b
Player
Eine andere Version,
OK ?
DigitMedium
play(DigitalMedium):void
DVDPlayer
CDPlayer
play(DigitalMedium):void
CD
play(DigitalMedium):void
DVD
ComboDrive
play(DigitalMedium):void
Seite 35
Klassenentwurf: Beispiel 4b
Nicht OK,
Mehrfachvererbung
Blödsinn ?!
DigitMedium
Player
play(DigitalMedium):void
DVDPlayer
CDPlayer
play(DigitalMedium):void
CD
play(DigitalMedium):void
DVD
ComboDrive
play(DigitalMedium):void
Seite 36
Klassenentwurf: Beispiel 4c
Player
DigitMedium
CD
play(DigitalMedium):void
DVD
CDPlayer
DVDPlayer
play(DigitalMedium):void
CDPlayer, DVDPlayer und
ComboDrive können Digitale Medien
abspielen.
Ein ComboDrive hat einen CD- und
einen DVD-Player.
play(DigitalMedium):void
ComboDrive
play(DigitalMedium):void
Besser so
Eine Klasse, die die Fähigkeiten von zwei anderen
kombiniert, ist nicht (unbedingt) als Ableitung von
beiden zu modellieren
Seite 37
Klassenentwurf: Beispiel 4c
DigitMedium
Player
play(DigitalMedium):void
CD
DVD
CDPlayer
CDPlayer, DVDPlayer und ComboDrive
DVDPlayer
play(DigitalMedium):void
spielen Digitale Medien ab.
play(DigitalMedium):void
Die Typ-Struktur bringt nicht zu Ausdruck, dass
CD-Player nur CDs abspielen können, DVDPlayer nur DVDs und nur ein Combo-Drive
ComboDrive
beide Arten eines digitalen Mediums.
play(DigitalMedium):void
Konsequenz: Aufrufe wie
cdPlayer.play( new DVD() )
enthalten keine Typfehler, werden vom
Compiler nicht bemängelt.
Das Typsytem bringt die Einschränkungen nicht
wie gewünscht zum Ausdruck!
Verbesserung möglich ?
Gegen die Intuition ? Nein !
Die realen Player erkennen dynamisch, was in sie hineingesteckt wird.
Sie spucken das Falsche wieder aus !
Seite 38
Klassenentwurf: Beispiel 4c
DigitMedium
Player
play(DigitalMedium):void
CD
DVD
CDPlayer
play(DigitalMedium):void
DVDPlayer
play(DigitalMedium):void
Die Ausdruckskraft des Typ-Systems von Java / UML ist
ComboDrive
begrenzt. Nicht alles, was
play(DigitalMedium):void
in einem informalen Entwurf / in der Realität als
Art / Unterart / Kategorie
verstanden werden kann oder soll,
lässt sich in
Klassen / Unterklassen / abstrakten Klassen / Schnittstellen
modellieren !
Verbesserung möglich ?
Nein !
Kovarianz im Parametertyp nicht erlaubt,
und dazu prinzipiell sehr problematisch.
Seite 39
Klassenentwurf: Beispiel 4d
Unterschied
zu Version
4c ?
DigitMedium
DVD
CD
PlayCD
play(CD):void
DVDPlayer
CDPlayer
<<realize>>
<<realize>>
PlayDVD
<<realize>>
play(DVD):void
<<realize>>
ComboDrive
Seite 40
Klassenentwurf: Beispiel 4d
DigitMedium
Statische Entscheidung über das zu
spielende Medium.
Keine Basisklasse / Schnittstelle Player !
DVD
CD
PlayCD
play(CD):void
DVDPlayer
CDPlayer
<<realize>>
<<realize>>
<<realize>>
PlayDVD
play(DVD):void
<<realize>>
ComboDrive
Java-Code ?
Seite 41
Klassenentwurf: Beispiel 5
Tier
frisst(Futter)
Futter
Gras
Fleisch
Kuh
frisst(Gras)
Was genau sagt das Diagramm aus?
Seite 42
Tiger
frisst(Fleisch)
Klassenentwurf: Beispiel 5
Tier
frisst(Futter)
Futter
Gras
Fleisch
Kuh
frisst(Gras)
1. Jedes Tier frisst jede Art von Futter
2. Jede Kuh
- frisst kuhig Gras
- frisst nach Art aller Tiere Futter
3. Jeder Tiger
- frisst nach Art der Tiger Fleisch
- frisst nach Art aller Tiere Futter
Seite 43
Tiger
frisst(Fleisch)
Klassenentwurf: Beispiel 5
Tier
frisst(Futter)
Futter
Gras
Fleisch
Kuh
frisst(Gras)
Was genau sagt das Diagramm aus?
Seite 44
Tiger
frisst(Fleisch)
Klassenentwurf: Beispiel 5
Tier
frisst(Futter)
Futter
Gras
Fleisch
Kuh
frisst(Gras)
1. Jedes Tier-Art kann jede Art von Futter fressen (ein Versprechen)
2. Jede Kuh
- frisst kuhig Gras
- sollte Futter fressen können – kann aber nicht!
3. Jeder Tiger
- frisst nach Art der Tiger Fleisch
- sollte Futter fressen können – kann aber nicht !
Seite 45
Tiger
frisst(Fleisch)
Th. Letschert
OOP 2
Dynamische Typprüfungen
Seite 46
Dynamische Typprüfung
Player
play(DigitMedium)
Ein Player spielt nur die
Medien ab, die zu ihm passen.
andere spuckt er wieder aus.
DigitMedium
CDPlayer
– play(CD)
play(DigitMedium)
DVDPlayer
– play(DVD)
play(DigitMedium)
CD
• Manche Typ-Einschränkungen werden
erst zur Laufzeit erkannt
Player jeder Art haben einen Einschub in
den man CDs und DVDs einlegen kann,
Erst beim Versuch des Abspielens stellt
man fest, dass es nicht geht
Realität und Modell stimmen überein:
Statisch ~ realem Aufbau
Dynamisch ~ realer Aktion
Seite 47
DVD
Annotation, bringt Dinge
zum Ausdruck, die nicht
in Diagrammform gesagt
werden können
private Methode:
Implementierung, nicht
Teil de Schnittstelle
(kein Einschub)
realisiert in Java
als dynamische
Typprüfung
Dynamische Typprüfung
public interface Player {
public void play(DigitMedium m);
}
public class CDPlayer implements Player {
private void play( CD cd ) {
System.out.println("Dudel CD");
}
public void play(DigitMedium m) {
if ( m instanceof CD )
play( (CD)m );
else
System.out.println("Medium nicht erkannt");
}
}
public class DVDPlayer implements Player {
private void play(DVD dvd) {
System.out.println("Spiele DVD ab");
}
public void play(DigitMedium m) {
if ( m instanceof DVD )
play( (DVD)m );
else
System.out.println("Medium nicht erkannt");
}
}
Seite 48
Definiere spezielle
Methode
Prüfe Argument
Rufe spezielle
Methode
Dynamische Typprüfung: als Abbild der „Realität“
Ein Player spielt nur die
Medien ab, die zu ihm passen.
andere spuckt er wieder aus.
public interface Player {
public void play(DigitMedium m);
}
public class CDPlayer implements Player {
private void play( CD cd ) {...}
public void play(DigitMedium m) {...}
}
public class DVDPlayer implements Player {
private void play(DVD dvd) { ... }
public void play(DigitMedium m) { ... }
}
Player
play(DigitMedium)
CDPlayer
– play(CD)
play(DigitMedium)
DVDPlayer
– play(DVD)
play(DigitMedium)
Modell und „Realität“ stimmen überein
In einen Player kann man DVDs und CDs einlegen,
beim Versuch sie abzuspielen wird das falsche Medium erkannt
Einschub und CD/DVD sind so geformt, dass man beide Medien einlegen kann:
sie sind statisch kompatibel
Seite 49
Dynamische Typprüfung: als Ausweg aus beschränktem Typsystem
Hund
frisst(Chappi)
WildHund
frisst(Fleisch)
Hund
frisst(Fleisch)
Fleisch
Chappi
WildHund
frisst(Fleisch)
keine Kontravarianz im Parametertyp bei
Redefinition in Java/UML (Beschränkung der
Modellierungssprachen Java/UML)
Fleisch
Chappi
Ein Hund darf nur mit
Chappi gefüttert werden.
Manche Typ-Einschränkungen können in UML / Java nicht ausgedrückt werden
Hunde haben Einschub in den man Chappi einlegen kann,
WildHunde haben einen Einschub in den man Fleisch einlegen kann
Chappi ist Fleisch
Der Versuch einen Hund mit (rohem) Fleisch zu füttern soll als Typfehler erkannt werden
„Realität“ und Modell stimmen nicht überein:
Fehler im statischen Code-Aufbau (Hund trifft auf Fleisch)
wird aber erst zur Laufzeit (dynamisch) erkannt
Seite 50
Ein Hund darf nur mit
Chappi gefüttert werden.
Typ-Modelle und ihre Umsetzung
Hund
frisst(Chappi)
WildHund
frisst(Fleisch)
Hund
frisst(Fleisch)
Fleisch
Chappi
UML/Java
OO-konform
ergänzen
WildHund
frisst(Fleisch)
Fleisch
Chappi
Es wird wegen der Beschränkungen von UML/Java
in dieses Diagramm umgeformt. „Hund frisst nur
Das Diagramm ist prinzipiell korrekt, kann aber so
nicht umgesetzt werden, da Java, UML
kontravariante Modifikationen im Parametertyp
redefinierter Methoden nicht akzeptieren.
Chappi“ ist OO-konform, aber aus technischen
Gründen nicht im Typsystem ausdrückbar.
Ein Tier frisst nur das Futter,
das zu ihm passt
Tier
frisst(Futter)
Tier
frisst(Futter)
Futter
Futter
OO-Konzepte
verlassen
Kuh
frisst(Gras)
Gras
Kuh
frisst(Futter)
Das Diagramm ist prinzipiell falsch, die Realisation
in Java (keine Redefinition) zeigt das Problem auf.
Chappi
Die Typeinschränkung „zu ihm passt“ ist weit
jenseits der OO-Ausdrucksmöglichkeiten und
des Typsystems von Java !
Seite 51
Typen und Modelle
Statische / dynamische Typrüfungen und Modellierung
Modelliere so, dass das UML/Java-Modell der (gewünschten) Realität
entspricht
Beachte die exakte Semantik von Java/UML
Modelliere so, dass möglichst viel an Fakten/Beziehungen als TypInformation ausgedrückt wird und statisch vom Compiler geprüft werden
kann. – Dazu sind sind OO-Konzepte und typisierte Sprachen da!
Beachte, dass sich nicht alles ausdrücken lässt.
Passt etwas nicht in das (UML-/Java-) Klassen/Typ-Konzept, dann ist es
Falsch / unsinnig / widersprüchlich / unausgegoren (wahrscheinlich),
oder
Jenseits der Ausdrucksmöglichkeiten von UML/Java (möglich)
Dokumentiere die Abweichung
Dokumentiere (UML) / programmiere (Java) um die
Beschränkungen herum (Dynamische Realisation der
statischen Konzepte des Modells)
Seite 52
Herunterladen