this(x, y)
this(x, y)
this(x, y)
Erfolgreiche ePaper selbst erstellen
Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.
Polymorphie (Vielgestaltigkeit)<br />
● = Methode oder Operation (gegeben durch Name) kann sich<br />
an Kontext anpassen<br />
● Unterscheiden:<br />
<br />
statische Polymorphie:<br />
- Überladen ⇒ Auswahl anhand der Parameter<br />
- auch in nicht-objektorientierten Sprachen, z.B. '/' für int und<br />
float<br />
<br />
dynamische Polymorphie (Polymorphie im engeren Sinn)<br />
- Überschreiben ⇒ Auswahl anhand des dynamischen Typs<br />
● Verhalten der Methode sollte nur angepasst, aber nicht<br />
grundsätzlich geändert werden (Gefahr von Programmierfehlern)<br />
EinfProg 86
Wiederverwendung und Erweiterbarkeit<br />
● sind wichtige Vorteile der OO-Programmierung:<br />
GeomFigur g;<br />
switch (eingabe) {<br />
}<br />
case 'r': g = new Rechteck();<br />
case 'k': g = new Kreis();<br />
case 'd': g = new Dreieck();<br />
// Programm enthält mehrere Zugriffe auf g:<br />
... g.zeichne(); ...<br />
... g.berechneFläche(); ...<br />
⇒ gleiches Programm kann für alle Unterklassen genutzt<br />
werden und muss bei Hinzufügen von Unterklassen nicht<br />
angepasst werden<br />
EinfProg 87
Konstruktoren und Vererbung<br />
Object<br />
Oberklasse<br />
Unterklasse<br />
Initialisierungen 1.-4. für Object<br />
Initialisierungen 1.-4. für Oberklasse<br />
Initialisierungen 1.-4. für Unterklasse<br />
Oberklassenkonstruktor wird rekursiv wie folgt ausgewählt:<br />
a) falls der Unterklassenkonstruktor mit super(..) oder <strong>this</strong>(..)<br />
beginnt, Aufruf des passenden Konstruktors<br />
b) sonst Aufruf des parameterlosen bzw. default-Konstruktors<br />
c) nicht vorhanden ⇒ Fehlermeldung des Compilers<br />
EinfProg 88
Das Schlüsselwort <strong>this</strong><br />
● <strong>this</strong> ist ein Verweis auf das aktuelle Objekt<br />
● Verwendung:<br />
<br />
Zugriff auf Attribute im Falle gleichnamiger lokaler<br />
Variablen<br />
void verschiebeNach(int x, int y) { <strong>this</strong>.x = x; <strong>this</strong>.y = y; }<br />
<br />
Zugriff auf andere Konstruktoren einer Klasse<br />
<strong>this</strong>(x, y);<br />
<br />
Aufruf einer Methode mit dem aktuellen Objekt als<br />
Parameter<br />
anderesObjekt.dessenMethode(<strong>this</strong>);<br />
EinfProg 89
Das Schlüsselwort super<br />
● super verweist auf das aktuelle Objekt, betrachtet als Objekt<br />
der Oberklasse (entspricht Typkonvertierung)<br />
● Verwendung:<br />
<br />
<br />
Aufruf eines Konstruktors der Oberklasse<br />
⇒ muss erste Anweisung im Unterklassen-Konstruktor sein<br />
⇒ super(..) und <strong>this</strong>(..) können nicht gemeinsam<br />
verwendet werden<br />
super(farbe);<br />
Zugriff auf überschriebene Methode der Oberklasse<br />
void zeichne() { // in Unterklasse<br />
}<br />
super.zeichne(); ...<br />
EinfProg 90
Typkonvertierung für Objekte 1<br />
● analog zu primitiven Typen, implizit in Richtung:<br />
Unterklasse ⇒ Oberklasse ⇒ ... ⇒ Object (Up-Cast)<br />
Rechteck r = new FarbigesRechteck();<br />
● Gegenrichtung erfordert expliziten Typecast (Down-Cast)<br />
Rechteck r = new FarbigesRechteck();<br />
FarbigesRechteck f = (FarbigesRechteck) r;<br />
● Typkonvertierung ist nur zwischen Vor- und Nachfahren<br />
möglich, nicht zwischen Geschwistern<br />
EinfProg 91
Typkonvertierung für Objekte 2<br />
● Typkonvertierung ändert die Sichtweise des Compilers (mehr<br />
nicht)<br />
● Compiler hat Sicht auf Objekte entsprechend des statischen<br />
Typs und verbietet Zugriffe auf scheinbar nicht vorhandene<br />
Attribute / Methoden<br />
● Typkonvertierung ändert den statischen Typ:<br />
Rechteck r = new FarbigesRechteck();<br />
r.verschiebe(2,3);<br />
// nicht zulässig: r.refill();<br />
((FarbigesRechteck) r).refill(); // ist zulässig<br />
EinfProg 92
Typkonvertierung für Objekte 3<br />
● Typkonvertierung hat keinen Einfluss auf den dynamischen<br />
Typ:<br />
FarbigesRechteck f = new FarbigesRechteck();<br />
// Typkonvertierung bewirkt nichts:<br />
((Rechteck) f).zeichne();<br />
// malt farbig aus!!!<br />
● Typkonvertierung passt den statischen an den dynamischen<br />
Typ an: (NeuerTyp) obj ist nur zulässig falls:<br />
- dynamischer Typ von obj = NeuerTyp oder<br />
- dynamischer Typ von obj ist Unterklasse von NeuerTyp<br />
EinfProg 93
Auswahl der Methode beim Überladen<br />
● erfolgt zur Übersetzungszeit anhand des statischen Typs<br />
● falls eindeutig bestimmt, wird die Methode mit den passenden<br />
Parametern (Anzahl, Typ) ausgewählt, gegebenenfalls mit<br />
impliziter Typkonvertierung<br />
Son son = new Son();<br />
public void test(Father father) { ... }<br />
test(son); // bewirkt Aufruf test(Father)<br />
● falls mehrere Methoden passen, wird diejenige mit den<br />
speziellsten Parametern ausgewählt (nicht eindeutig ⇒<br />
Fehlermeldung des Compilers)<br />
Son son = new Son(); Father wer = new Son();<br />
public void test(Father father) { ... }<br />
public void test(Son son) { ... }<br />
test(son); // bewirkt Aufruf test(Son)<br />
test(wer); // bewirkt Aufruf test(Father)<br />
EinfProg 94
Überdecken von Variablen<br />
● = Redefinition eines Attributs in der Unterklasse:<br />
public class Punkt {<br />
int x, y;<br />
...<br />
}<br />
public class FeinPunkt extends Punkt {<br />
double x, y;<br />
...<br />
}<br />
● überdeckte Variablen sind gültig, aber nicht sichtbar<br />
● Auswahl erfolgt zur Übersetzungszeit, laut statischem Typ<br />
● Zugriff möglich: super.x bzw. ((Punkt) fp).x<br />
●<br />
Überdecken von Variablen vermeiden!<br />
EinfProg 95
Überdecken von Klassenmethoden<br />
Klassenmethoden werden nicht überschrieben, sondern überdeckt:<br />
class Oben {<br />
static String greeting() { return "Guten Tag"; }<br />
String name() { return "Fritz"; }<br />
}<br />
class Unten {<br />
static String greeting() { return "Hallo"; }<br />
String name() { return "Susi"; }<br />
}<br />
class Test {<br />
public static void main(String[] args) {<br />
Oben obj = new Unten();<br />
Out.println( obj.greeting() + obj.name() );<br />
}<br />
}<br />
⇒ Guten Tag Susi<br />
vermeiden!<br />
EinfProg 96
Programmierparadigmen und -sprachen<br />
imperativ<br />
● prozedural<br />
● objektorientiert<br />
Fortran, Ada<br />
Smalltalk, C#<br />
deklarativ<br />
● funktional<br />
● logisch<br />
Haskell, ML, Lisp<br />
Prolog, Oz<br />
● Skriptsprachen<br />
Perl, PHP, Python<br />
EinfProg 97
Funktionale Programmierung<br />
● Programm = Abbildung Eingaben → Ausgaben<br />
● Programm = mathematische Funktion, durch Ausdruck<br />
beschrieben<br />
● Ausführung Programm = Berechnung Ausdruck<br />
● funktionales Programm umfasst:<br />
- Funktionsdefinitionen<br />
- Ausdruck: enthält Funktionsaufrufe, liefert Ergebnis<br />
● nicht vorhanden: Anweisungen, Variablen, Seiteneffekte<br />
EinfProg 98
Funktionen<br />
● Abbildungen Eingabe → Ausgabe<br />
● Funktionsdefinition:<br />
square :: Int -> Int pechzahl :: Int<br />
square n = n * n pechzahl = 13<br />
● Funktion mit mehreren Parametern:<br />
max:: Int -> Int -> Int<br />
max x y<br />
| x >= y = x<br />
| otherwise = y<br />
● Funktionsanwendung:<br />
square 5 = 5 * 5<br />
square (2+4) = (2+4) * (2+4)<br />
EinfProg 99
Kombination von Funktionen<br />
● Kombination bei Funktionsanwendung:<br />
square pechzahl<br />
max (square 3, max(square pechzahl, 7))<br />
● oder auch in Funktionsdefinition:<br />
maxSquare :: Int -> Int -> Int<br />
maxSquare x y = max ( square x, square y)<br />
● oder mit Verkettungsoperator:<br />
power4 :: Int -> Int<br />
power4 = square . square<br />
● x, y, max, power4 etc. sind Bezeichner (keine Variablen!)<br />
- nur einmalige Wertzuweisung<br />
EinfProg 100
Listen - Beispiel<br />
Liste = vordefinierte Datenstruktur (vergleichbar Arrays in Java)<br />
mit veränderlicher Anzahl von Einträgen<br />
● vordefinierte Funktionen: reverse, map etc.<br />
Bild: X 0 0<br />
X 0 0<br />
X 0 0<br />
X X X<br />
[ [X, 0, 0],<br />
[X, 0, 0],<br />
[X, 0, 0],<br />
[X, X, X] ]<br />
flipH Bild:<br />
X X X<br />
X 0 0<br />
X 0 0<br />
X 0 0<br />
[ [X, X, X],<br />
[X, 0, 0],<br />
[X, 0, 0],<br />
[X, 0, 0] ]<br />
flipH = reverse<br />
EinfProg 101
Listen – Beispiel (Forts.)<br />
Bild: X 0 0<br />
X 0 0<br />
X 0 0<br />
X X X<br />
[ [X, 0, 0],<br />
[X, 0, 0],<br />
[X, 0, 0],<br />
[X, X, X] ]<br />
flipH Bild:<br />
0 0 X<br />
0 0 X<br />
0 0 X<br />
X X X<br />
[ [0, 0, X],<br />
[0, 0, X],<br />
[0, 0, X],<br />
[X, X, X] ]<br />
flipH = map reverse<br />
Funktionen sind 'first-class citizens' ⇒ Verwendung entspricht<br />
Datentypen wie int, Bild<br />
EinfProg 102
Ausblick<br />
Rekursion ist von zentraler Bedeutung:<br />
fac :: Int -> Int<br />
fac n<br />
| n == 0 = 1<br />
| n > 0 = fac (n-1) * n<br />
Problem funktionaler Sprachen: Ein-/Ausgabe (sind zeitlos)<br />
Literatur: Simon Thompson. Haskell: The Craft of Functional<br />
Programming<br />
EinfProg 103