06.11.2013 Aufrufe

this(x, y)

this(x, y)

this(x, y)

MEHR ANZEIGEN
WENIGER ANZEIGEN

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

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!