Objektorientierte Programmiersprachen (in Arbeit) © Günter Riedewald Die Folien sind eine...
-
Upload
edzard-dreyer -
Category
Documents
-
view
105 -
download
3
Transcript of Objektorientierte Programmiersprachen (in Arbeit) © Günter Riedewald Die Folien sind eine...
Objektorientierte Programmiersprachen (in Arbeit)
© Günter RiedewaldDie Folien sind eine Ergänzung zur Vorlesung und nur für den internen
Gebrauch konzipiert.
Literatur
Abadi, Martin, Cardelli, Luca: A Theory of Objects
Springer, 1996
Bruce, K. B.:Foundations of Object-Oriented Programming Languages: Types and Semantics
The MIT Press, 2002
Budd, Timothy: An Introduction to Object-Oriented Programming
Addison-Wesley, 2002
Brügge, B., Dutoit, A. H.: Objektorientierte Softwaretechnik mit UML, Entwurfsmustern und Java
Pearson Studium, 2004
Poetzsch-Heffter, Arnd: Konzepte objektorientierter Programmierung
Springer, 2000
Diverse Literatur zu objektorientierten Sprachen, z.B.:
Bishop, Judith: Java lernen
Addison-Wesley, 2001
Deitel, H. M., Deitel, P. J.: C++ How to Program
Prentice Hall, 1994
Goldberg, A., Robson, D.: Smalltalk-80: The Language
Addison-Wesley, 1989
Gore, Jacob: Object Structures
Building Object-Oriented Software Components with Eiffel
Addison-Wesley, 1996
Kratzer, Klaus Peter: ADA Eine Einführung für Programmierer
Hanser, 1996
Lamprecht, G.: SIMULA – Einführung in die Programmiersprache
Vieweg, 1988
Schiedermeier, R.: Programmieren mit JavaEine methodische Einführung
Pearson Studium, 2005
Bücher über Konzepte von Programmiersprachen, z.B.:
Louden, Kenneth, C.: Programmiersprachen
Grundlagen, Konzepte, Entwurf
International Thomson Publishing, 1994
Objektorientierte PrototypsprachenBlaschek, Günther:
Object-Oriented Programming with Prototypes
Springer, 1994
Entwurfsmuster in OOPSGamma, E., Helm, R., Johnson, R., Vlissides, J.:
Design Pattern: Elements of Reusable Object-Oriented Software
Addison-Wesley, 1995
Beispiel:
BEGIN CLASS liste;
BEGIN INTEGER wert; REF(liste) nachf; END;
REF(liste) l;
l :- NEW liste;
l.wert := 1; l.nachf :- NEW liste;
l.nachf.wert := l.wert + 1;
END
Beispiel: komplexe Zahlen in Simula CLASS Complex(x,y);
REAL x,y;BEGIN
REAL re,im;REAL PROCEDURE realpart;BEGIN
realpart := re;END realpart;REAL PROCEDURE imaginarypart;BEGIN
imaginarypart := im;END imaginarypart;PROCEDURE add(y); REF(Complex) y;BEGIN
re := re + y.realpart;im := im + y.imaginarypart;
END add;...
comment – Initialisierungscode;re := x;im := y;END Complex;
Beispiel: abstrakte Syntaxbäume arithmetischer Ausdrücke (Kantorovič-Bäume)
Wurzel eines Teilbaumes: Operationssymbol (codiert)
Blätter eines Teilbaums: Operanden (Konstante, Variable, Teilbaum)
CLASS form; BEGIN END;
form CLASS const(val); REAL val; BEGIN END;
form CLASS var(nam, val); TEXT nam; REAL val;
BEGIN END;
form CLASS triple(lop, op, rop);
REF(form) lop, rop; INTEGER op; BEGIN END;
REF(form) f, g, h;
f :- NEW const(10);
g :- NEW var(´g´, 9);
h :- NEW triple(NEW triple(f, plus, g), plus, f);
Liefert
+
+ 10
10 g
Beispiel als Verbund (Record)
10.0 f
lop
op plus plus
rop
nam ´g´ g
val 9.0
Vereinigung von Verbunden mit nichtleerer Oberklasse - Beispiel
CLASS klasse(a,b); REAL a, b;
BEGIN REAL x, y; ... END;
klasse CLASS klasse1(c, d); REAL c, d;
BEGIN REAL u, v;
u := c + d; v := x + y;
END;
Definitionsschachtel für NEW klasse1(1, 2, 3, 4)
a 1.0
b 2.0
x w1
y w2
c 3.0
d 4.0
u 7.0
v w1+w2
Klassendefinition circle CLASS circle(center, radius);REF(point) center; REAL radius;BEGIN
REAL PROCEDURE area;BEGIN
area := pi * radius * radius;END area;
…END circle; Klassendefinition rectangle CLASS rectangle(center, width, height);REF(point) center; REAL width, height;BEGIN
REAL PROCEDURE area;BEGIN
area := width * height;END area;
…END rectangle;
Oberklasse closedFigure CLASS closedFigure(center);REF(point) center;VIRTUAL:
REAL PROCEDURE area;BEGIN …END closedFigure;
Neudefinition von circle closedFigure CLASS circle(radius);REAL radius;BEGIN
REAL PROCEDURE area;BEGIN
area := pi * radius * radius;END area;
…END circle;
Neudefinition von rectangle closedFigure CLASS rectangle(width, height);REAL width, height;BEGIN
REAL PROCEDURE area;BEGIN
area := width * height;END area;
…END rectangle;
Programmstück REF(point) x,y; REF(closedFigure) f; REF(rectangle) s; REF(circle) c;x :- NEW point(0.0,0.0);y :- NEW point(1.0,-1.0);s :- NEW rectangle(x,1.0,1.0);c :- NEW circle(y,1.0);f :-s;f.area;f :-c;f.area;
Allgemeine Beziehungen zwischen Objekten
Ein Objekt X benutzt ein Objekt Y, wenn
- eine Methode von X eine Nachricht an Y schickt: mX: ...Y.n ...
- Eine Methode von X das Objekt Y
a) erzeugt: mX: ...GY ... (Generator G)
b) als Parameter übergeben bekommt: X.mX(Y...)
c) als Ergebnis zurückgibt: mX: ... return Y
Hat-ein-Beziehung:
Ein Objekt X hat ein Attribut, das das Objekt Y oder eine Referenz darauf als Wert hat.
Teil-von-Beziehung: Spezialfall der Hat-ein-Beziehung, wobei Y als Teil von X betrachtet wird.
Erreichbarkeitsbeziehung: transitive Hülle der Hat-ein-Beziehung
Ist-ein-Beziehung: Jedes Objekt o einer Klasse U ist gleichzeitig Objekt einer Oberklasse zu u.
Beispiel: Personenstruktur an der Uni Studenten: Name, Geburtsdatum, Adresse, Immatrikulationsdatum, Immatrikulationsnummer, Fachbereich, Studiengang, Fachsemester, wahrscheinliches Abschlussdatum
Wissenschaftliche Mitarbeiter: Name, Geburtsdatum, Adresse, Einstellungsdatum, Beschäftigungsnummer, befristet/unbefristet, wahrscheinliches Beschäftigungsende, Fachbereich
Nichtwissenschaftliche Mitarbeiter: Name, Geburtsdatum, Adresse, Einstellungsdatum, Beschäftigungsnummer, Fachbereich
Hochschullehrer: Name, Geburtsdatum, Adresse, Berufungsdatum, Beschäftigungsnummer, Kategorie, Fachbereich
Person
Name, Geburtsdatum, Adresse, Beschäftigungsbeginn, FB
Student Angestellte
+ Imm.-Nr., Studiengang, + Beschäftigungsnr.
Fachsemester, wahrsch.
Abschlußdatum
Wissen. Mitarbeiter Nichtwiss. Mit. HSL
+ Befristung, wahr. + Kategorie
Beschäftigungsende
Polymorphismus
Einteilung nach Stansifer:Überladung
ad hoc
implizite Umwandlung
Polymorphismus
Untertyp
universell
parametrisiert
Polymorphismus nach Programmiersprachen:
1. Nichtobjektorientiert:
- Überladene Operatoren: gleicher Name, unterschiedliche Operation
- Polymorphe Operatoren: gleicher Name, gleiche Operation auf unterschiedlichen Datentypen
- Implizite Umwandlung: automatische Typkonvertierung von Operanden gemäß syntaktischer Position
- Einschließender Polymorphismus: Operation für gegebenen Typ schließt auch Daten eines abgeleiteten Typs ein
- Parametrischer Polymorphismus: Operation für unterschiedliche Datentypen mit Typparameter
2. Objektorientiert
- Gleiche Nachricht an Objekte unterschiedlicher Klassen löst unterschiedliche Operationen aus
- Gleicher Variabler können Objekte unterschiedlicher Typen eines „Vererbungspfades“ zugewiesen werden unterschiedliche Operationen bei gleicher Nachricht (dynamisches Binden)
Erscheinungsformen in OOPS:
• Ad hoc:
a) Gleicher Name für Methoden in voneinander unabhängigen Klassen
A B
m m
a b
a.m b.m
b) Gleicher Name für zwei unterschiedliche Methoden in gleicher Klasse (mit unterschiedlicher Signatur)
c) Überschriebene geerbte Operation (Konkretisierung bei Übergang von abstrakter zu konkreter Klasse, Verfeinerung, völlig neue Implementation)
• Einschließender Polymorphismus (Vererbungspolymorphismus): Eine in einer Oberklasse definierte Methode wird auch auf die Objekte der abgeleiteten Klassen angewendet.
• Typparameter in generischen Einheiten
Statisches und dynamisches BindenKovarianz und Kontravarianz
Binden:
Hier: Zuordnung von Methoden (Operationen) zu Methodennamen (Operationssymbolen)
Statisches Binden: Binden zur Übersetzungszeit
Dynamisches Binden: Binden zur Laufzeit
Beispiel: Kovarianz, Kontravarianz
Tier TIER Ok OK
F(Tier t)
Katze KATZE HUND Hund Uk UK
F(Katze t)
Ok einObjekt = NEW Uk(...);
Hund einHund = NEW Hund;
einObjekt.F(einHund);
1. Fall:
Statisches Binden: Da einObjekt vom Typ Ok ist (Vereinbarung), muss F aus der Klasse OK genommen werden. Daher ist der Parameter vom Typ Tier. Der aktuelle Parameter einHund ist vom Typ Hund und damit Untertyp von Tier.
Dynamisches Binden: einObjekt referiert zur Laufzeit zu einem Objekt des Typs Uk (Klasse UK). Dynamisch wird deshalb F von UK mit dem formalen Parameter vom Typ Katze ausgewählt. Der Typ des aktuellen Parameters einHund ist aber Hund, welches kein Untertyp von Katze ist. Demzufolge wird ein Laufzeitfehler gemeldet.
2. Fall:
Im Programmteil wird die erste Anweisung ausgetauscht gegen
Ok einObjekt = NEW Ok(...);
Keine Differenz in den Sichten bei statischer und dynamischer Bindung
3. Fall:
Änderung des 1. Falles: F in OK bekommt den Parametertyp Katze und F in UK den Parametertyp Tier
Statisches Binden liefert einen Typfehler zur Übersetzungszeit (Auswahl von F aus Ok mit gefordertem Parametertyp Katze; Typ des aktuellen Parameters ist aber Hund). Dynamisches Binden ergibt keine Probleme (Auswahl von F aus Uk mit gefordertem Parametertyp Tier; Typ des aktuellen Parameters ist der Untertyp von Tier Hund).
Während bei den Klassen von der „größeren“ zur „kleineren“ Klasse übergegangen wird, geschieht das beim Parameter von F genau umgekehrt.
Kontravarianz
Beispiel:OK Ok einObjekt = NEW Uk(...);
Katze Ergebnis = einObjekt.g(...);
Katze g(...)
UK Für Ergebnistypen von Methoden gilt bei dynamischer Bindung das
Tier g(...) Prinzip der Kovarianz.
Smalltalk
Grundprinzipien:• Jedes Ding ist ein Objekt.• Jedes Objekt ist eine Instanz einer Klasse.• Jede Klasse ist Unterklasse einer anderen Klasse.• Jedes Objekt wird durch Nachrichten aktiviert. Klassen sind Objekte und damit Instanzen von
Metaklassen. Festlegung von Object als oberste Klasse
(Durchbrechung der unendlichen Definition)
Charakteristika von Smalltalk-Klassen:
• Enthalten streng private Instanzvariablen (Speicherung des Objektzustands)
• Enthalten ein Nachrichtenprotokoll (Nachrichtenschnittstelle): Methoden zur Änderung oder zum Lesen des Objektzustands
• Enthalten Oberklasse
• Objekterzeugung durch new
• Objektzugriff über Zeiger
Beispiel: Definition der Klasse COMPLEX Class name: COMPLEXSuperclass: ObjectInstance variables: re imMethods :
realPart re
imagPart im
setReal : xre x
setImag : y im y
+ y (COMPLEX new setReal : (re + (y realPart)))
setImag: (im + (y imagPart))...
x (COMPLEX new setReal: 1.0) setImag: 1.0y (COMPLEX new setReal: 1.0) setImag: - 1.0z x + y
Klassenstruktur Boolean – True – FalseBoolean
ifTrue:
ifFalse:
xor:
True False
ifTrue: ifFalse: ifTrue: ifFalse:
not not
or: or:
and: and:
true false
Methodenidentifikation:Vor.: Nachricht m an Objekt o der Klasse K
a) Suche von m in K:
Erfolg, wenn m gefunden wurde
b) Fortsetzung der Suche in der Oberklasse:
Erfolg, wenn m dort vorhanden ist
Bei Misserfolg Fortsetzung in weiterer Oberklasse
c) Suche erreicht Object und m ist nicht vorhanden:
Nachricht DoesNotUnderstand: m an Objekt o und Identifikationsprozess mit DoesNotUnderstand
d) Wird erneut Object erreicht, erfolgt eine Standardfehlermeldung
Beispiel: Fachbereichscodes Class name: FachbereichscodesSuperclass: ObjectInstance variables: names, codesMethods :´´Create an instance´´new
super new. ´´Create initial empty arrays´´initialise
[names Array new: 0codes Array new: 0].
´´Test for empty´´isEmpty
names isEmpty. ´´Test for inclusion of a given name´´include: name
(self indexOf: name) ~= 0.
´´Create a new entry with the given name and return index´´newIndexOf: name
[self grownames at: names size put: name names size].
´´Stretch table by one element and put in new name´´grow
[oldNames oldCodesoldNames namesoldCodes codesnames Array new: names size + 1codes Array new: codes size + 1names replaceFrom: 1 to: oldNames size with: oldNamescodes replaceFrom: 1 to: oldNames size with: oldCodes].
´´Number of table entries´´size
names size. ´´Fetch the code for a department´´at: name
[indexindex self indexOf: nameindex = 0ifTrue: [self error: ‘Error—Name not in table’]ifFalse: [ codes at: index]].
´´Install a new code; create entry if necessary´´at: name put: code
[index index self indexOf: nameindex = 0ifTrue: [index self newIndexOf: name] codes at: index put: code].
´´Look-up index of a given department name´´indexOf: name
[1 to: names size do:[:index (names at: index) = name ifTrue: [ index]]
0].
´´Ausdrücke´´dCodes Fachbereichscodes new erzeugt neue InstanzdCodes initialise initialisiert names und codesdCodes isEmpty names und codes sind leerdCodes at: ´Physics´ put: 100 Physics wird mit 100,dCodes at: ´Chemistry´ put: 110 Chemistry mit 110 unddCodes at: ´Biology´ put: 120 Biology mit 120 eingetragendCodes isEmpty die Tabelle ist nicht leerdCodes size sie enthält 3 EintragungendCodes at: ´Chemistry´ liefert 110dCodes includes ´Physics´ liefert truedCodes includes ´Computing´ liefert false
Object
MetaClass Class
ZClass Z
AClass Aerben von Metaklassen Klassen
Instanz sein von
Eiffel
Charakteristische Prinzipien und Konstrukte:• Eiffel ist streng getypt:
- Festlegung von Typen durch Deklaration
- Statische Kompatibilität
- Eindeutig bestimmbarer Typ• Typen:
- Referenztypen: Zeiger auf Objekte
- Erweiterte Typen: Objekttypen
- Basistypen: INTEGER, REAL, DOUBLE, CHARACTER, BOOLEAN
• Klassen als Implementation von ADTs und Grundlage für Objekttypen
• Klasse als Ding der Übersetzungszeit, Objekt als Ding der Laufzeit
• Vor- und Nachbedingungen für Methoden als Basis der Methode des Programming (Design) by Contract:
„{V} q {N}, p ruft q auf“ bedeutet „Wenn p die Gültigkeit der Vorbedingung V garantiert, dann garantiert auch q die Gültigkeit der Nachbedingung N.“
• Klasseninvariante, Schleifeninvariante
• Sprachkonstrukt für Ausnahmebehandlung
• Mehrfachvererbung
• Generische Klassen als Implementierung parametrisierter ADTs
• Abstrakte Klassen in Form zurückgestellter Klassen
• Gezielte Verdeckung von Merkmalen
Klassenstruktur:
[<Indexierung>]
<Klassenkopf>
[<formale generische Parameter>]
[<veraltete Klasse>]
[<Vererbung>]
[<Erzeugung>]
[<Merkmale>]
[<Invariante>]
end [--class <Klassenname>]
Beispiel: generische Klasse für Hashtabellen hash-fähiger Elementeindexing
names: h_table;access: key,direct;representation: array;size: fixed, resizable
class HASH_TABLE[T, V HASHABLE]inherit TABLE[T, V]
redefineloadend
creation
makefeature
remove(k: V) is--Remove entry of key krequire
valid_key: is_valid(k)do…ensure
not has(k)end; --remove
make(n: INTEGER): BOOLEAN is--Allocate space for n items…end; --make
load …
ok: BOOLEAN is--Was last operation successful?do
Result := control = 0end; --ok
control: INTEGER;Max_control: INTEGER is 5;…
invariant
0<= control; control <= Max_controlend –class HASH_TABLE
Anpassung ererbter Merkmale:
• Überschreibung:
– Überschreibbar: Signatur, Implementation, Spezifikation (Vor- und Nachbedingung)
Bedingung: Eine überschriebene Signatur muss entsprechend Konformitätsregeln konform zur alten Signatur sein; „Beachtung“ der Bedingungen.
– Gründe für ein Überschreiben: Unvollständigkeit oder Inkorrektheit für die neue Klasse oder ungenügende Effizienz
– Ankündigung durch
redefine <Merkmalsliste>
• Umbenennung:
- rename <alter Merkmalsname> as <neuer
Merkmalsname>
- Ziele:
Vermeidung von Namenskonflikten, die Ermöglichung des Zugriffs zu gleichnamigen aber unterschiedlichen Merkmalen und die Einführung sprechender Bezeichnungen
• Implementation von in den Elternklassen zurückgestellten Merkmalen:
Kennzeichnung in Elternklassen mit deferred als abstrakt und Spezifikation mit abstrakten Eigenschaften; Implementierung unter Beachtung der Typkonformitätsregel und der Bedingungen
• Löschen der Implementation eines geerbten Merkmals:
undefine <Liste von Merkmalsnamen>
Die angeführten Merkmale werden als zurückgestellt (in der Elternklasse) betrachtet.
Beispiel: Umbenennung
class C
inherit
A
rename f as g
end;
B
feature
…
h(x,y:T) is
do
g(x,y) Verwendung von f aus A
f(y) Verwendung von f aus B
…
end
end –class C
Beispiel: abstrakte Klasse
deferred class COMPARABLE
feature
infix ´´<´´(other: like current):
BOOLEAN is
deferred
end
…
end –class COMPARABLE
class STRING
inherit
COMPARABLE
redefine ´´<´´
end
feature
infix´´<´´(other: like current):
BOOLEAN is
…
end
…
end –class STRING
Vererbungshierarchie:
GENERAL
PLATFORM
ANY
...
NONE
Vererbungsrelationen:
B Eltern
C Kind (Erbe)
A A, B, C sind Vorgänger (Vorfahren) von C
A, B, C sind Nachfolger (Nachfahren) von B A
A, B sind echte Vorgänger von C
C B, C sind echte Nachfolger von A
Beispiel:inherit
C
rename
...
export {D,E,F} Die Merkmale f, g und h der Klasse C werden
f,g,h an die Klassen D, E und F „weitergegeben“.
{M,N} Die Merkmale k, l und m der Klasse C werden
k,l,m an die Klassen M und N „weitergegeben“.
redefine
...
end
Situationen mit Beachtung der Konformität:• x := y :Der Typ von y muss konform zum Typ von x sein.
• Typen aktueller Parameter müssen konform zu den Typen der entsprechenden formalen Parameter sein.
• Das Überschreiben eines ererbten Attributs muss so geschehen, dass der neue Typ konform zum alten Typ ist (Kovarianz).
• Beim Überschreiben einer Funktion muss der neue Ergebnistyp konform zum alten Ergebnistyp sein.
• Beim Überschreiben einer Routine müssen die neuen Argumenttypen konform zu den entsprechenden alten Argumenttypen sein.
Beispiele: Mehrfachvererbung (wiederholte Vererbung)
• Einfache wiederholte Vererbung
class B
inherit
A; A
feature
...
end –class B
Festlegung: A wird nur einfach geerbt.
• Ererbte Routine wird modifiziert und unter altem Namen bereitgestellt, während die alte Version einen neuen Namen bekommtclass B
inherit ...
A feature
rename make is
make as A_make do
end; A_make
A …
redefine end
make …
select end –class B
make
end
A A
make make
ererbt und B ererbt und
umbenannt überschrieben
A_make
make
• Auswahl eines Merkmals bei Ringstruktur
A
f
B C
ererbt undf überschrieben f
ererbt und D ererbt und
umbenannt umbenannt
bf
cf
a: A; b: B; c: C; d: D;
...
b := d; c := d; a := d; -- erlaubt wegen Konformität
b.f; -- Aufruf von bf
c.f; -- Aufruf von cf
a.f; -- Aufruf von bf oder cf?
Auswahl durch select-Klausel in D:class D
inherit B
rename f as bf
select bf
...
end;
Varianten der Objekterzeugung:
Voraussetzung: Klasse C definiert Objekttyp T, x sei vom Typ T
• C enthalte keine Erzeugungsprozedur:
!!x bedeutet
a) Erzeugung eines neuen Objekts als Instanz vom Typ T
b) Initialisierung aller Objektkomponenten durch Standardwerte
c) Setzen der Referenz von x auf das Objekt
• C enthalte eine Erzeugungsroutine cp:
!!x.cp(...) bedeutet
a) Erzeugung eines neuen Objekts als Instanz vom Typ T
b) Initialisierung aller Objektkomponenten durch Standardwerte
c) Aufruf von cp(...) angewendet auf das Objekt
d) Setzen der Referenz von x auf das Objekt
• Erzeugung eines Objekts vom Typ V konform mit T: !V!x oder !V!x.cp(...)
Beachte folgende Situationen:• Klassendefinition enthält keine creation-Klausel: !!
<Variable> mit Standardinitialisierung wird genutzt.
• Klassendefinition enthält leere creation-Klausel (besteht nur aus creation): Es können keine Objekte als Instanzen dieser Klasse erzeugt werden.
• Auf Klienten zugeschnittene creation-Klausel (wie feature-Klausel).
• Eine Erzeugungsroutine verliert beim Vererben ihren Erzeugungscharakter, wenn sie nicht explizit in der creation-Klausel der abgeleiteten Klasse steht.
Beispiel: komplexe Zahlen
class COMPLEXcreation
makeComplexfeature {NONE}
re, im: REAL; -- nicht exportiertfeature
makeComplex(x, y:REAL) isdo
re := x;im := y;
end; --makeComplex
realPart: REAL isdo Result := re end;
imaginaryPart: REAL is
do Result := im end;
add(y: COMPLEX) isdo
re := re + y.realPart;im := im + y.imaginaryPart;
end; --add
subtract(y: COMPLEX) is
dore := re - y.realPart;im := im - y.imaginaryPart;
end; --subtract
negate isdore := -re;im := -im;end; --negate
multiply(y: COMPLEX) is
local r, i: REAL;dor := re * y.realPart – im * y.imaginaryPart;i := im * y.realPart + re * y.imaginaryPart;re := r; im := i;end; --multiply
divide(y: COMPLEX) is ...
end; --class COMPLEX
x, y, z: COMPLEX;…!!x.makeComplex(1.0, 1.0) ; --erzeuge ein Objekt mit der komplexen Zahl
--1.0 + i 1.0 und setze eine Referenz von x zu --ihm
!!y.makeComplex(2.0, -1.0); --erzeuge ein Objekt mit der komplexen Zahl--2.0 – i1.0 und setze eine Referenz von y zu ihm
z := clone(x); --z zeigt auf eine Kopie des von x gezeigten--Objekts
z.add(y); --z zeigt auf die Summe der von x und y--gezeigten komplexen Zahlen
Zusicherungen in Eiffel:
• Klasseninvariante: Eigenschaften aller Objekte der Klasse zu stabilen Situationen
• Schleifeninvariante:
- Zweck der Schleife in Form von Beziehungen zwischen Programmvariablen
- gilt vom Eintritt bis zum Verlassen der Schleife (bei Verlassen gilt zusätzlich Abbruchbedingung)
- variant-Klausel kontrolliert über Integer-Ausdruck Erreichung des Schleifenendes (Verminderung in jedem Durchlauf, aber nie negativ)
- Schleifenstruktur:
from
... Initialisierung
invariant
... Schleifeninvariante
variant
... Variant-Klausel
until
... Bedingung für Schleifenende
loop
... Schleifenkörper
end
• check-Klausel: an allen Anweisungsstellen erlaubt zur Formulierung von lokalen Eigenschaften
• Vor- und Nachbedingungen für RoutinenProzedurdefinition:
<Prozedurname>(<Argumente>) is
require
... Vorbedingung
local
... Deklaration lokaler Elemente
do
... Prozedurkörper
ensure
... Nachbedingung
end
Ausnahmesituationen:
• Falscher Alarm: Meldung einer Ausnahme ohne Einfluss auf weitere Abarbeitung normale Fortsetzung
• Wiederaufnahme: Softwarekomponente mit vorbedachten Alternativen für den Ausnahmefall Fortsetzung nach ausgewählter Alternative
• Organisierte Panik: keine Möglichkeit der Vertragserfüllung Objekte werden in akzeptablen Zustand versetzt und es erfolgt eine Misserfolgsmeldung an Kunden
try_once_or_twice is--Solve problem using method 1 or, if unsuccessful, method 2localalready_tried: BOOLEAN;
doif not already_tried then method_1 else method_2 endrescueif not already_tried then already_tried := true;retryend
end –try_once_or_twice
try_and_record is--Attempt to solve problem using method 1 or, if unsuccessful, method 2.--Set impossible to true if neither method succeeded, false otherwise.local
already_tried: BOOLEAN;do
if not already_tried then method_1elseif not impossible then method_2end
rescueif already_tried then impossible := true end;already_tried := true;retry
end –try_and_record
Java
Ziele und Charakteristika:
• Softwareaustausch zwischen unterschiedlicher Hardware
• Als selbständige OOPS entwickelt, aber mit imperativen Sprachkonstrukten
• Elementare Datentypen wie in imperativen Sprachen, aber in Klassen einpackbar (wrapper)
• Gewisse Möglichkeiten der Metaprogrammierung
• Parallelarbeit durch Ausführungsstränge (threads)
• Objektlokale und klassenlokale Variablen und Methoden
• Schnittstellenkonzept
• Applet-Nutzung
• Netzprogrammierung
Klasse, Objekt
Klasse: neuer Objekttyp + Implementierung
Aufbau einer Klasse:[<Modifikatorenliste>] class <Klassenname>
{<Liste von Attribut-, Konstruktor- und Methodendeklarationen>}
Methodendeklaration:[<Modifikatorenliste>] <Ergebnistyp> <Methodenname>
([<Parameterliste>])
[<throws-Deklaration>] <Methodenrumpf>
Konstruktor:
• Dient der Erzeugung von Objekten und der Initialisierung der objektlokalen Variablen
• Konstruktorname = Klassenname
• Bereitstellung durch Nutzer oder Standard
• Aufruf: new <Klassenname> (<aktuelle Parameter>)
Programm:
• Kollektion von Klassen
• Eine Klasse enthält Klassenmethode main:
public static void main (String[ ] argf) {...}
Imperative KonstrukteWerte, Variablen, Ausdrücke
Werte:
• Elemente eines Datentyps
• Objektreferenzen
• Referenz null
Operationen:
• Auf Objekten oder deren Referenzen
• Auf Basisdatentypen
• Auf allen Datentypen (z.B. ==, !=, =)
Zuweisung <Variable> = <Ausdruck>:
• Berechnung des Ausdruckwertes und Zuweisung zur Variablen auf der linken Seite
• Wert der Zuweisung = Wert des Ausdrucks
Operandentypen: bei ungleichen Typen
• Implizite Konvertierung: ganzahlige Typen in größere Bereiche oder Gleitkomma
• Explizite Konvertierung:
(<gewünschter Typ>) <Ausdruck>
(Gewünschter Typ und Ausdruckstyp müssen miteinander vereinbar sein.)
Imperative KonstrukteAnweisungen, Blöcke
Anweisungen:
• Ausdruck (Zuweisung, Methodenaufruf, arithmetischer Ausdruck, logischer Ausdruck)
• Bedingte Anweisungen:
- if (<logischer Ausdruck>) <Anweisung>
- if (<logischer Ausdruck>)
<Anweisung1> else <Anweisung2>
• Mehrfache Alternative (switch-Anweisung)
• Schleifen:
- while (<logischer Ausdruck>) <Anweisung>
- do <Anweisung> while (<logischer Ausdruck>)
- for (<Init-Ausdruck>; <logischer Ausdruck>; <Ausdruck>) <Anweisung>
Block:
• Variablendeklarationen und Anweisungen gemischt und eingeschlossen in { }
• Zählt als zusammengesetzte Anweisung
Beispiele:• result = 1;
for (i = 2; i <=n; i = i + 1) result = result * i;
• i = 2;
while (i <= n)
{result = result * i; i = i + 1;}
• switch (n) {
case 0:...; break;
case 1:...; break;
...
case 10:...; break;
default:...; }
Spezielle Anweisungen:
• break: Verlassen der umfassenden Anweisung (Beispiel siehe oben)
• return [<Ausdruck>]: Verlassen eines Methodenrumpfes mit eventuellem Ergebnis
Ausnahmebehandlung
Aufbau der try-Anweisung:
try
<Block> enthält Anweisungen, die eine
Ausnahme verursachen
könnten
catch (<Ausnahmetyp> <Bezeichner>) <Block>
...
catch (<Ausnahmetyp> <Bezeichner>) <Block>
[finally <Block>]
Beispiel:• int m;
String str = ´´007L´´;
try {
m = Integer.parseInt(str);
}
catch (NumberFormatException e) {
System.out.println(´´str keine int-Konstante´´);
m = 0}
System.out.println(m);
Allgemeine Abarbeitung der try-Anweisung:
• Fehlerfreie Ausführung des try-Blocks:
- Ausführung des finally-Blocks
- Normale Terminierung der try-Anweisung und Fortsetzung mit nachfolgender Anweisung
• Abrupte Beendigung des try-Blocks durch Ausnahme Ex:
- Passender catch-Block existiert:
1. Ausführung des catch-Blocks
2. Ausführung des finally-Blocks
3. Normale Terminierung der try-Anweisung und Fortsetzung mit nachfolgender Anweisung
- Sonst (kein passender catch-Block):
1. Ausführung des finally-Blocks
2. Wird die try-Anweisung von weiterer try-Anweisung umfasst, erfolgt Weitergabe von
Ex an sie; ansonsten erfolgt abrupte Terminierung mit Ausnahme Ex.
Direkte Auslösung einer Ausnahme mit throw-Ausdruck.
try-Block Ausnahme
Keine Ausnahme
catch-Block
finally-Block
Propagierung von Ausnahmen:
• Innerhalb von Hierarchien von Throw-Blöcken zum unmittelbar umfassenden throw-Block
• Von aufgerufener Methode zum Aufrufer durch throws-Deklaration im Methodenkopf
[<Modifikatorenliste>] <Ergebnistyp> <Methodenname> ([<Parameterliste>])
[<throws-Deklaration>] <Methodenrumpf>
Strukturen mit Klassen, Sichtbarkeit
Strukturen:
• Paket als Zusammenfassung logisch zusammengehöriger Klassen
• Vererbungsstruktur für Klassifikation
• Verschachtelung von Klassen (innere Klassen) zur Erleichterung der Handhabung
Anwendungaspekte für Pakete:
• Gute Strukturierung
• Einteilung in Namensräume und Festlegung von Zugriffsrechten
• Separate Übersetzung
• Wiederverwendung von Klassen
Steuerung des Zugriffs zu Konstrukten eines Pakets:
• Kein Modifikator (default access): paketlokaler Zugriff
• public: uneingeschränkte Nutzung
• private: klassenlokaler Zugriff
• protected: Zugriff durch abgeleitete Klassen
Person
Druckbar
Student Angestellte
wissMitarbeiter nwMitarbeiter HSL
class Person {...}interface Druckbar {void drucken();}class Student extends Person
implements Druckbar {...}class Angestellte extends Person
implements Druckbar {...}class wissMitarbeiter extends Angestellte
implements Druckbar {...}class nwMitarbeiter extends Angestellte
implements Druckbar {...}class HSL extends Angestellte
implements Druckbar {...}
Typen
Basisdatentypen Referenz- oder Objekttypen
Klassentypen SchnittstellentypenFeldtypen
Beispiel: Dynamisches Binden für Untertypen des Schnittstellentyps Druckbar
class NumDruck{
private static int Nummer = 1;
private static void DruckMitNum(Druckbar d){
System.out.println(´´Posten´´+Nummer+´´:´´);
d.drucken(); Nummer ++;
}
}
Vererbung:• Geerbt werden alle Attribute, Methoden und inneren
Klassen der Oberklassen, falls ein Zugriff erlaubt ist
Spezialfall Konstruktoren:
Im Unterklassenkonstruktor kann direkt auf den Oberklassenkonstruktor durch super(<Parameter>) oder implizit als erste Anweisung des Unterklassenkonstruktors auf den parameterlosen Oberklassenkonstruktor zugegriffen werden.
• Anpassung einer geerbten Methode: Ersetzen durch Methode gleicher Signatur oder Zugriff auf Methode der Oberklasse durch super.<Methodenname>(<Parameter>) mit Ergänzung
• Zusätzliche Attribute, Methoden und innere Klassen
class LinkedList{private Entry header = new Entry(null, null, null);private int size = 0;LinkedList(){header.next = header;header.previous = header;}
ListElem getLast(){…}ListElem removeLast(){…}void addLast(ListElem e){…}int size(){…}
private static class Entry{private ListElem element;private Entry next;private Entry previous;
Entry(ListElem element, Entry next, Entry previous){…}
}}
LinkedList Entry
header element nullsize 3 next
previous Entry Entry Entry
element element elementnext next nextprevious previous previous ListElem ListElem ListElem
class MyClassIsMyCastle {private static int streetno = 169;
private static class FirstFloor {private static class DiningRoom {
private static int size = 36;private static void mymessage() {
System.out.print(´´I can access streetno´´);System.out.println(´´:´´+streetno);
}}
}
private static class SecondFloor {private static class Bathroom {
private static int size = 16;private static void mymess() {
System.out.print(´´I can access the ´´);System.out.print(´´dining room size: ´´);System.out.println(´´ ´´+FirstFloor.DiningRoom.size);
}}
}
public static void main(String[] argv){FirstFloor.DiningRoom.mymessage();SecondFloor.Bathroom.mymess();
}}
MyClassIsMyCastle
streetno 169 MyClassIsMyCastle
FirstFloor
DiningRoom FirstFloor SecondFloor
size 36
mymessage DiningRoom BathRoom
SecondFloor
BathRoom
size 16
mymess
main
class LinkedList {private Entry header = new Entry(null, null, null);private int size = 0;…private static class Entry {…}
class ListIterator {private int nextIndex = 0;private Entry next = header.next;
boolean hasNext(){
return nextIndex != size;}
ListElem next(){
if (nextIndex == size)throw new NoSuchElementException();
ListElem elem = next.element;next = next.next;nextIndex ++;return elem;
}}
ListIterator listIterator(){Return new ListIterator();
}}
LinkedList
header element nullnext nullprevious null
size 0
Entry
ListIterator
nextIndex 0next element
nextprevious
hasNextnext
listIterator
Beispiel: Anwendung des Schnittstellenkonzepts auf die Implementierung des Beobachtermusters (nach A. Poetzsch-Heffter: Konzepte objektorientierter Programmierung)
Schnittstelle:
interface Beobachter {
void steigen(Aktie a);
void fallen(Aktie a);
}
Aktienklasse:
import java.util.*;
public class Aktie {
private String name;
private int kurswert;
private ArrayList beobachterliste;
Aktie(String n, int anfangswert){
name = n;
kurswert = anfangswert;
beobachterliste = new ArrayList();
}
public void anmeldenBeobachter(Beobachter b) {
beobachterliste.add(b);
}
public String getName() {
return name;
}
public int getKurswert() {
return kurswert;
}
void setKurswert(int neuerWert) {
int alterWert = kursWert;
kursWert = neuerWert>0 ? neuerWert : 1;
ListIterator it = beobachterliste.listIterator();
if(kursWert > alterWert) {
while(it.hasNext() ) {
Beobachter b = (Beobachter)it.next();
b.steigen(this);} }
else {
while(it.hasNext() ) {
Beobachter b = (Beobachter) it.next();
b.fallen(this);}
}
}
}
Aktieninteressent:
class Kunde1 implements Beobachter {
private boolean besitzt = false;
public void fallen(Aktie a) {
if(a.getKurswert() < 300 && !besitzt) {
System.out.println(´´Kauf von ´´+a.getName() );
besitzt = true;
}}
public void steigen(Aktie a) {
if(a.getKurswert() > 400 && besitzt) {
System.out.println(´´Verkauf von ´´+a.getName() );
besitzt = false;
}}
Schlafend E/A beendet E/A-blockiert
interrupt Zeit abgelaufen E/Asleep
yieldNeu Rechenbereit Rechnend
start Scheduling Tot
wait
interrupt notify/ Monitor besetzt
notifyAllMonitor
Wartend frei Monitor-blockiert
Prozesszustände und -übergänge
terminiert
Erzeugung von Strängen:
1. Ableitung einer neuen Thread-Klasse K aus der Klasse Thread mit Überschreiben der Methode run:
class K extends Thread{
...
public void run(){
...
}
}
Thread meinThread = new K();
...
meinThread.start();
2. Ableitung einer neuen Klasse K von einer beliebigen Klasse O mit gleichzeitiger Implementierung der Schnittstelle Runnable:
class K extends O
implements Runnable
...
public void run(){
...
}
}
Runnable meinZiel = new K();
Thread meinThread = new Thread(meinZiel);
...
meinThread.start();
PACKAGE Keller_Verwaltung IS -- TypvereinbarungenTYPE Keller IS PRIVATE; -- Unterprogrammvereinbarungen FUNCTION Leer (K: Keller) RETURN Boolean;-- Leer zeigt an, ob der Keller leer ist. PROCEDURE Push (K: IN OUT Keller; Was: IN Integer);-- Ein Element wird in den Keller gefuellt. PROCEDURE Pop (K: IN OUT Keller);-- Das Element an der Kellerspitze wird entfernt. FUNCTION Read (K: Keller) RETURN Integer;-- Das Element an der Kellerspitze wird gelesen. FUNCTION Groesse (K: Keller) RETURN Natural;-- Gibt die Anzahl der Kellerelemente an.
-- AusnahmesituationenKellerueberlauf: EXCEPTION RENAMES Storage_ErrorLeerer_Keller: EXCEPTION; PRIVATE
TYPE Komponente;TYPE Komponenten_Zeiger IS ACCESS Komponente;TYPE Komponente IS RECORD
Information: Integer;Weiter: Komponenten_Zeiger;
END RECORD;TYPE Keller IS RECORD
Anker: Komponenten_Zeiger := 0;Groesse: Natural := 0;END RECORD;
END Keller_Verwaltung;
Paket X Kindpaket X.Y
Deklarationen öffentlich öffentlichprivat privat
Körper
GENERICSize: Positive;TYPE Item IS PRIVATE;
PACKAGE Stack ISPROCEDURE Push (E: IN Item);PROCEDURE Read (E: OUT Item);Overflow, Underflow: EXCEPTION;
END Stack;
PACKAGE BODY Stack ISTYPE Table IS ARRAY (Positive RANGE <>) OF Item;Space: Table (1..Size);Index: Natural := 0;
PROCEDURE Push (E: Item) ISBEGIN IF Index >= Size Then RAISE Overflow END IF;
Index := Index + 1;Space (Index) := E;
END Push;
PROCEDURE Read (E: OUT Item) ISBEGIN IF Index = 0 THEN RAISE Underflow; END IF;
E := Space(Index);Index := Index – 1;
END Read;END Stack;
- TYPE Tastenart IS (Zeichen, Funktion, Pfeil, Unbekannt); TYPE F_Nummer IS RANGE 1..10; TYPE Richtung IS (N, O, S, W); TYPE Taste (Art: Tastenart := Unbekannt) IS RECORD CASE Art IS
WHEN Zeichen Z: Character;WHEN Funktion F: F_Nummer;WHEN Pfeil R: Richtung;WHEN Unbekannt NULL;
END CASE; END RECORD;
WITH Calendar, People;PACKAGE Alert_System IS
TYPE Alert IS TAGGEDRECORD
Time_Of_Arrival: Calendar.Time;Message: Text;
END RECORD;PROCEDURE Display(A: IN Alert);PROCEDURE Handle(A: IN OUT Alert);PROCEDURE Log(A: IN Alert);
TYPE Low_Alert IS NEW Alert WITH NULL
RECORD;
TYPE Medium_Alert IS NEW Alert WITHRECORD
Action_Officer: People.Person;END RECORD;
-- neue Handle-OperationPROCEDURE Handle(MA: IN OUT Medium_Alert);
TYPE High_Alert IS NEW Medium_Alert WITH
RECORDRing_Alarm_At: Calendar.Time;
END RECORD;-- neue Handle-OperationPROCEDURE Handle(HA: IN OUT High_Alert);PROCEDURE Set_Alarm(HA: IN High_Alert);
END Alert_System;
Alert
Low_Alert Medium_Alert
High_Alert
PACKAGE Sets ISSUBTYPE Element_Type IS Natural;TYPE Set IS ABSTRACT TAGGED NULL RECORD;
FUNCTION Empty RETURN Set IS ABSTRACT;FUNCTION Union (Left, Right: Set) RETURN Set IS ABSTRACT;FUNCTION Intersection (Left, Right: Set) RETURN Set IS
ABSTRACT;FUNCTION Unit_Set (Element: Element_Type) RETURN Set IS
ABSTRACT;PROCEDURE Take (Element: OUT Element_Type;
From: IN OUT Set) IS ABSTRACT;END Sets;
-- Private Vereinbarung des Typs Geometrisches_Objekt im Paket Geo PACKAGE Geo IS
TYPE Geometrisches_Objekt IS ABSTRACT TAGGED PRIVATE; TYPE Pixel_Koordinaten IS
RECORDX, Y: Integer;
END RECORD ;
TYPE Bildschirmfarbe IS RANGE 0..15 ;
PROCEDURE Verlagere (Was: IN OUT Geometrisches_Objekt;Wohin: IN Pixel_Koordinaten);
PROCEDURE Zeige (Was: IN Geometrisches_Objekt) IS Abstract;
PRIVATETYPE Geometrisches_Objekt IS TAGGED
RECORDFarbe: Bildschirmfarbe;Bezugspunkt: Pixel_Koordinaten;
END RECORD;END Geo;
-- Private Vereinbarung des Typs Flaechenobjekt im Paket-- Geo.Flaechenobjekte PACKAGE Geo.Flaechenobjekte IS
TYPE Flaechenobjekt IS ABSTRACT NEW Geometrisches_Objekt WITH PRIVATE; PRIVATE
TYPE Flaechenobjekt IS ABSTRACT NEWGeometrisches_Objekt WITHRECORD
Gefuellt: Boolean;END RECORD;
END Geo_Flaechenobjekte;
-- Private Vereinbarung des Typs Kreis im Paket-- Geo.Flaechenobjekte.Kreise PACKAGE Geo.Flaechenobjekte.Kreise IS
TYPE Kreis IS ABSTRACT NEW FlaechenobjektWITH PRIVATE;
PRIVATE
TYPE Kreis IS ABSTRACT NEW FlaechenobjektWITHRECORD
Radius: Float;END RECORD;
END Geo.Flaechenobjekte.Kreise;
-- Private Vereinbarung des Typs Rechteck im Paket-- Geo.Flaechenobjekte.Rechtecke PACKAGE Geo.Flaechenobjekte.Rechtecke IS
TYPE Rechteck IS ABSTRACT NEWFlaechenobjekt WITH PRIVATE;
PRIVATE
TYPE Rechteck IS ABSTRACT NEWFlaechenobjekt WITH
RECORDEckpunkt_2: Pixel_Koordinaten;
END RECORD; END Geo.Flaechenobjekte.Rechtecke;
Paketstruktur
Geo
Flaechenobjekte
Kreise Rechtecke
TypstrukturGeometrisches_Objekt Farbe
Bezugspunkt
Flaechenobjekt FarbeBezugspunktGefuellt
Kreis Farbe Rechteck FarbeBezugspunkt BezugspunktGefuellt GefuelltRadius Eckpunkt_2
Anwendung des Pakets Geo -- Ausgabe einer Reihung geometrischer ObjekteWITH Geo;PACKAGE Geo_Reihungen IS
TYPE Geo_Zeiger IS ACCESS Geo.Geometrisches_Objekt´Class;
TYPE Geo_Reihung IS ARRAY (Positive RANGE <>) OF Geo_Zeiger;
PROCEDURE Zeige (Was: IN Geo_Reihung); END Geo_Reihungen;
WITH Geo; USE Geo;PACKAGE BODY Geo_Reihungen IS
PROCEDURE Zeige (Was: IN Geo_Reihung) ISBEGIN
FOR I IN Was´Range LOOPZeige (Was (I).ALL);
END LOOP;END Zeige;
END Geo_Reihungen;
a parent
x
y
b parent c parent
y y
z z
Merkmalsobjekt Allgemeines Merkmalsobjekt
parent clone+ print-
a parent b parent c parent
y y yz z z
c n
x 15 x 15y 4 c.clone n y 4m1 m1
x 15 n ADDS x 15n REMOVE y m1 VAR z z 10
10 z m1METHOD m2 … ; m2ENDADDS
Prototyp P P-Objekt P1
Klasse P Eltern P-Objekt P2
Kind Kind
Prototyp N Klasse N N-Objekt n