Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

54
Telecooperation/RBG Technische Universität Darmstadt Copyrighted material; for TUD student use only Grundlagen der Informatik I Thema 17: Statische Typisierung Subtyp-Polymorphie Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

description

Grundlagen der Informatik I Thema 17: Statische Typisierung Subtyp-Polymorphie. Prof. Dr. Max Mühlhäuser Dr. Guido Rößling. Worum geht es in dieser Vorlesung?. Das “magische Dreieck” der Programmiersprachen. Welche Invarianten gibt es in meinem Programm?. sicher. mächtig. einfach. - PowerPoint PPT Presentation

Transcript of Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Page 1: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Telecooperation/RBG

Technische Universität Darmstadt

Copyrighted material; for TUD student use only

Grundlagen der Informatik IThema 17: Statische Typisierung

Subtyp-Polymorphie

Prof. Dr. Max MühlhäuserDr. Guido Rößling

Page 2: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Worum geht es in dieser Vorlesung?

• Das “magische Dreieck” der Programmiersprachen

2

sicher

einfach mächtig

Welche Invarianten gibt esin meinem Programm?

Wie einfach ist ein Programmzu verstehen?

Welche Ideen können in der Sprachedirekt ausgedrückt werden?

Wir hatten diese Abwägung schon mal:Die Diskussion pro/contra Zuweisungen

Page 3: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Werte und Typen

• Definition: Ein Typ ist eine Menge von Werten, die irgendeine interessante gemeinsame Eigenschaft haben

– Gemeinsame Eigenschaften gemeinsame Operationen!

• Ist ein Wert v Element eines Typs T, sagen wir v hat den Typ T

• Beispiel: {0,1,2,…} ist ein Typ: die natürlichen Zahlen

– Beispiel: {1,2,3,4,5,6} ist ein Typ: die Menge der deutschen Schulnoten

– Ein Wert kann zu mehreren Typen passen

• Andere Typen: Symbol, String, … 3

Page 4: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Werte und Typen• Viele Abstraktionsmechanismen in Programmiersprachen

beruhen auf der Abstraktion Wert Typ

– Wir abstrahieren (* 4 4), (* 3 3) zu (square 4), (square 3), wobei square = (lambda (x) (* x x))

– Wir gehen implizit davon aus, dass das x in der Funktionsdefinition den Typ Number hat, denn nur für diesen ist * definiert

• Funktionen haben ebenfalls einen Typ, den wir mit Hilfe von Verträgen ausgedrückt haben

– z.B. (lambda (x) (* x x)) hat den Typ number number

4

Page 5: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Typfehler

• Ein Typfehler tritt auf, wenn eine berechnende Einheit (z.B. ein Wert oder eine Funktion) in einer zu dem Konzept, das sie darstellt, inkonsistenten Art und Weise benutzt wird

– Hardwarefehler• unerlaubter Instruktionsfehler• unerlaubter Speicherverweis

– Versehentliche Semantik• z.B. kann in int_add(3, 4.5) der Wert 4.5 falsch

interpretiert werden als ein Ganzzahlwert, der nicht mit 4.5 in Beziehung steht

5

Page 6: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Typsysteme

• Ein Typsystem ist ein Mechanismus, der jedem Wert einen Typ (oder Menge von Typen) zuordnet und verhindert, dass Typfehler auftreten.

6

Beispiel: Scheme verhindert den Typfehler durch Abbruch des Programms

Diese Fehlermeldung bekommen wir aber erst, wenn wirdas Programm ausführen!

> (define x 'hello)> (+ x 5)+: expects type <number> as 1st argument, given: 'hello; other arguments were: 5

Page 7: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Statische Typsysteme• In einem statischen Typsystem kann man ein

Programm vor der Ausführung auf mögliche Typfehler überprüfen

– Ein großer Vorteil, weil man den Fehler bemerkt, bevor es zu spät ist

– Zuverlässiger als “Testen”, weil Tests nur die Anwesenheit, aber nicht die Abwesenheit von Fehlern überprüfen können

• In kompilierten Sprachen geschieht diese Typüberprüfung häufig während der Kompilierung

• Auch interpretierte Sprachen können aber statische Typsysteme haben

• Java ist ein Beispiel für statisch typisierte Sprachen

7

Page 8: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Statische Typsysteme• Werden Typfehler erst zur Laufzeit erkannt, spricht

man von dynamisch typisierten Sprachen

• Werden Typfehler gar nicht erkannt, spricht man von untypisierten Sprachen– Beispiel: Assembler

• In der Realität werden viele Programmiersprachen statisch geprüft, garantieren aber keine Sicherheit (manchmal schwaches Prüfen genannt)

• Manche Sprachen haben ein statisches Typsystem, welches aber nicht alle Typfehler erkennt– “gut genug”, 80/20 Regel

8

Page 9: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Ebenen von Typsicherheit

Schwache statische Prüfung

(Starke) statische Prüfung

Dynamische Prüfung

C, C++, Pascal Java, ML Smalltalk, Scheme, Scriptsprachen

9

Page 10: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

class Counter { int n; Counter(int value) { n = value; } //...}

Statisch typisierte Sprachen

• Beispielsprachen: Java, C++, C#, Haskell, ML

• Der Typ jeder Variable kann zur Kompilierzeit bestimmt werden– Die meisten statisch typisierten Sprachen

erreichen dieses Ziel, indem sie explizite Deklarationen der Typen verlangen.

10

Es ist in Java unmöglich, eine Variable zu deklarieren, ohne ihren Typ anzugeben.

Page 11: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Statisch typisierte Sprachen

• Statisch typisierte Sprachen mit impliziten Deklarationen verwenden vorgegebene Konventionen– FORTRAN: Variablen, die mit I, J, K, L, M, N

anfangen, enthalten Ganzzahlen

• Es gibt statisch typisierte Sprachen mit Typdeduktionsfähigkeiten (type inference) – Gegeben folgende Deklaration, kommt der ML-

Compiler zu der Folgerung, dass x eine Zahl ist.

11

fun square(x) = x * x

Page 12: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Dynamisch typisierte Sprachen

• In dynamisch typisierten Sprachen wird der Typ einer Variable dynamisch gebunden

• Es sind keine Typdeklarationen notwendig.• Sehr bequem! Ermöglicht die Definition von

flexiblen Funktionen, für die der Typ der Argumente egal ist.

• Beispiele:– Scheme, Smalltalk, Self, Python, etc.

12

Page 13: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Typprüfung• Typprüfung stellt sicher, dass die Operanden

eines Ausdrucks kompatibel mit den Operatoren sind– Sowie dass es sich bei einer Nachricht an einem Objekt um

eine Methode in der Schnittstelle des Objektes handelt

• Kompatible Typen sind entweder die gleichen Typen, oder können implizit ineinander konvertiert werden.– Automatische Typkonvertierung wird coercion genannt– Siehe die Diskussion über automatische

Typkonvertierungen in Abschnitt 2.5.2 SICP (V 9)– integer rational real complex

• Ein Typfehler entsteht bei der Anwendung einer Operation an einem Operanden mit einem unerlaubten Typ. 13

Page 14: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Typprüfung

• Bei statischen Typbindungen kann die Typprüfung statisch (zur Kompilierzeit) stattfinden (statische Typprüfung).

• Bei dynamischen Typbindungen kann die Typprüfung nur zur Laufzeit geschehen (dynamische Typprüfung).

• In einigen statisch typisierten Sprachen können einige Typprüfungen auch nur zur Laufzeit durchgeführt werden– Mehr dazu später

14

Page 15: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Statische vs. dynamische Typprüfung

15

String x = "hello";x = x * 10;

Zur Kompilierzeit:x = x * 10; ^^^^^^* not defined for type String

(define x 'hello)(+ x 1)

Zur Laufzeit:+: expects type <number> as 1st argument, given: hello; other arguments were: 1

Ungültige Verwendung von Variablen werden von dem Compiler nicht entdeckt und führen zu einem Laufzeitfehler

Page 16: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Statische vs. dynamische Typprüfung

16

String s = new String("Hello World"); s.determineLength();

Compile program…

Error in ... (line 3)

s.determineLength(); ^^^^^^^^^^^^^^^^

Method determineLength() not defined for type String

Page 17: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Statische vs. dynamische Typprüfung

17

(define (make-counter n) (define (increment) (set! n (+ n 1)) n) (define (dispatch msg) (cond ((eq? msg 'increment) increment) (else (error "undef operation:" msg))) ) dispatch)

(define ca (make-counter 1))(ca 'increment)(ca 'decrement)

Zur Laufzeit:undef operation: decrement

Page 18: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Statisches Typisieren ist konservativ• Ein perfekter statischer Typprüfer wäre ein

Typprüfer, der einen Typfehler dann und genau dann meldet, wenn der Typfehler während der Programmausführung auftreten wird

• Ein perfekter Typprüfer existiert nicht!– Folgt aus bestimmten Unentscheidbarkeitsergebnissen

aus der Theoretischen Informatik („Halteproblem“)• Somit nähern statische Typprüfer das

Laufzeitverhalten an: Sie sind konservativ– Sie “bleiben auf der sicheren Seite”– Wann immer ein Typfehler zur Laufzeit auftreten würde,

wird er vom Typprüfer entdeckt– Es gibt aber auch Programme, die vom Typprüfer

abgelehnt werden, die ohne Fehler ausgeführt werden könnten

18

Page 19: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Sollten Sprachen statisch geprüft werden?

Argumente für statisches Prüfen• Wirtschaftlichkeit der Ausführung

– z.B. arithmetisch, Methodenauflösung• Wirtschaftlichkeit des Kompilierens

– separate Kompilierung möglich• Wirtschaftlichkeit der Entwicklung in kleinem Umfang

– kann einen großen Teil von Routineprogrammierfehlern abfangen, besser als unvollständiges manuelles Testen

– bietet Dokumentation zum Quelltext an– Gebrauch des Typprüfers als Entwicklungswerkzeug, z.B. eine

Klasse umbenennen, um alle Referenzen darauf zu entdecken• Wirtschaftlichkeit der Entwicklung im großen Umfang

– Teams können Schnittstellen vereinbaren, die vom Compiler erzwungen werden

– Abstrahieren weg von der Implementierung großer Komponenten

19

Page 20: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Sollten Sprachen statisch geprüft werden?

Argumente gegen statisches Prüfen• Quelltext langatmiger

– viele offensichtliche Deklarationen• Inflexibilität

– Statisches Prüfen ist konservativ– probieren Sie das z.B. in Java

• Identitätsfunktion implementieren ohne Typumwandlung• Das Argument von equals(Object other) sollte den selben

Typ haben wie der Empfänger• clone() gibt immer eine Instanz desselben Typs wie der

Empfänger zurück• Viele Mechanismen wurden entwickelt, um mit diesen

Problemen umzugehen– Typinferenz, Typsysteme höherer Ordnung, ...– Aber diese Mechanismen können sehr komplex sein

20

Ein statischer Typprüfer ist ein mächtiger Helfer, solange die Programme in den Grenzen dessen liegen, was das Typsystem ausdrücken kann. Wenn wir über diese Grenzen hinausgehen wollen, steht uns das Typsystem im Weg.

Page 21: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Statischer und dynamischer Typ

• Der Typ eines Objekts ist immer die Klasse, deren Instanz es ist – Dieser Typ ist immer dynamisch an ein Objekt

gebunden.• Bei Variablen unterscheiden wir den statischen

und dynamischen Typ:– Der statische Typ einer Variablen ist der Typ,

an den sie bei der Deklaration gebunden wird.• Er verändert sich während der Ausführung

nicht.

– Der dynamische Typ zu einem Zeitpunkt t während der Ausführung ist der Typ des Objekts, auf das die Variable zum Zeitpunkt t verweist.

21

Page 22: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Shape shape = null; shape = new Circle(10, 20, 16); shape.draw(canvas); shape = new Rectangle(10, 10, 20, 5); shape.draw(canvas);

Statischer und dynamischer Typ

22

Hier wird in einem Programm ein und derselbe Name an verschiedenen Stellen benutzt, um zwei verschiedene Objekte zu bezeichnen. Eine solche Variable nennt man polymorph (griechisch "vielgestaltig").

In der realen Welt gibt es mehrere Objekte namens shape, und welches gemeint ist, hängt vom Kontext ab. In der Welt der grafischen Objekte ist es genauso.

Statischer Typ der Variablen shape

Der dynamische Typ der Variablen shape ist zu diesem Zeitpunkt Circle

Der dynamische Typ von shape ist ab diesem Zeitpunkt Rectangle

Page 23: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

public void main(String[] args) { Circle shape = null; shape = new Rectangle(10, 10, 20, 5); // ...}

Statischer und dynamischer Typ

• Kann man ein grafisches Objekt beliebigen Typs an eine beliebige Variable zuzuweisen?– Natürlich nicht! Darum geht es ja bei Typsystemen:

• Ein Typ regelt, wie ein Name benutzt werden kann• Der Typ schränkt die Menge der Werte ein, die einer

Variablen zugewiesen werden können … und die darauf ausführbaren gültigen Operationen

– Nur Instanzen einer direkten oder indirekten Subklasse ihres statischen Typs können an eine Variable zugewiesen werden.

23

H

Page 24: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Das Substitutionsprinzip

Ein Objekt (grafisches Objekt) einer Subklasse kann überall dort verwendet werden, wo ein Objekt (grafisches Objekt) einer Superklasse erwartet wird. Diese Substituierbarkeitsrelation ist transitiv.

24

• An var kann jedes Objekt der Klassen B, C und all ihrer Subklassen zugewiesen werden (Transitivität der Substituierbarkeit).

• Jede in A und B deklarierte Operation kann auf var (auf jedem in var gespeicherten Objekt) aufgerufen werden.

• Es ist nicht erlaubt, auf var eine Operation aufzurufen, die in C deklariert ist, aber nicht in A oder B.

A

B

C

Die Deklaration B var; impliziert:

Page 25: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Das Substitutionsprinzip

• Ein Objekt einer Subklasse kann einem Objekt einer Superklasse als Repräsentant dienen: – Seine Struktur enthält alle Attribute eines Objekts

der Superklasse– Es kann alle Operationen ausführen, die für Objekte

der Superklasse definiert wurden

• Das Gegenteil trifft jedoch nicht zu! – Ein Objekt einer Superklasse ist nicht spezialisiert

genug, um die Rolle des Objekts einer Subklasse zu spielen.

25

Die Deklaration B var; heißt nicht “var hat genau den Typ B“; sondern “das Verhalten von var ist konform zu B“.

Page 26: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Substitutionsprinzip: eine Analogie

26

• Ein Kunde einer Autovermietung bestellt ein vierrädriges Fahrzeug zum Transport einiger Möbelstücke von A nach B• Es ist in Ordnung, wenn er einen Kleinbus erhält.

Ein Kleinbus hat vier Räder.• Hat er jedoch einen Lastwagen bestellt, dann ist es

nicht OK, ihm ein beliebiges vierrädriges Fahrzeug zu geben• Der Kleinbus könnte zu wenig Ladefläche haben.

Fahrzeug

Zweirädrig Vierrädrig

Motorrad Fahrrad Lastwagen Kleinbus

Page 27: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Shape shape = null; shape = new Circle(10, 20, 16); shape.draw(canvas); shape = new Rectangle(10, 10, 60, 20); shape.draw(canvas);

Subtyp-Polymorphie

27

Gleicher Programmtext, aber verschiedene BedeutungPOLYMORPHIE

Page 28: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Subtyp-Polymorphie

28

• Jedes grafische Objekt befolgt Befehle gemäß seiner Programmierung:

paint(g);Circle vs. Rectangle

• Dies ist besonders interessant, wenn mehrere grafische Objekte dieselben Befehle erhalten, sie aber unterschiedlich implementieren.

Page 29: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Noch einmal Subtyp-Polymorphie

29

Nun, da wir Schnittstellen kennen, betrachten wir statische und dynamische Typen von Variablen, Subtyp- Polymorphie und Substituierbarkeit gemeinsam.

Zu diesem Zweck werden wir das UML-Klassendiagram auf dieser Folie benutzen. Es zeigt eine einfache Typ- und Klassenhierarchie.

Page 30: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Noch einmal Subtyp-Polymorphie

30

Obwohl das Modell "Klassendiagramm" genannt wird, ist es eigentlich ein Typdiagramm.

Jede Java-Klasse und Schnittstelle deklariert einen benutzerdefinierten Datentyp.

Das Modell stellt fünf Typen dar:vier Klassen und eine Schnittstelle.

Page 31: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Noch einmal Subtyp-Polymorphie

31

Von einem implementierungs-

unabhängigen (also typorientierten)

Standpunkt aus betrachtet, repräsentiert jedes der fünf

Rechtecke einen Typ.

Vom Standpunkt der Implementierung aus

betrachtet, sind vier dieser Typen durch Klassen

definiert, und einer durch eine Schnittstelle.

Page 32: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Implementierungs-Hierarchie

32

class Base {  public String m1() {    return "Base.m1()";  }  public String m2(String s) {    return "Base.m2(" + s + ")";  }}

interface Itype {  String m2(String s);  String m3();}

class Derived extends Base implements Itype {  public String m1() {    return "Derived.m1()";  }  public String m3() {    return "Derived.m3()";  }}

Page 33: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Implementierungs-Hierarchie

33

class Derived2 extends Derived {  public String m2(String s) {    return "Derived2.m2(" + s + ")";  }  public String m4() {    return "Derived2.m4()";  }}

class Separate implements IType {  public String m1() {    return "Separate.m1()";  }  public String m2(String s) {   return "Separate.m2(" + s + „)";  }  public String m3() {  return "Separate.m3()";  }}

Page 34: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Referenzen als Bullaugen

34

Derived2 derived2 = new Derived2();

Dieser Ausdruck tut zweierlei: er• deklariert die explizit getypte

Referenzvariable derived2,• bindet derived2 an ein neu

erzeugtes Derived2-Objekt.

Die Derived2-Referenz kann als Menge von Bullaugen gesehen werden, durch die das Derived2-Objekt gesehen wird.

Es gibt ein Bullauge pro Operation im Typ Derived2. Das Derived2-Objekt bildet jede Derived2-Operation auf geeigneten Code ab, wie in der Implementierungs-Hierarchie vorgesehen.

Page 35: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Referenzen als Bullaugen

35

Derived2 derived2 = new Derived2();

Beispiel:• Das Derived2-Objekt bildet

m1() auf Code ab, der in der Klasse Derived definiert ist.

• Darüber hinaus überschreibt dieser Code die Implementierung von m1() in der Klasse Base.

Eine Derived2-Referenzvariable kann auf die überschriebene Methode m1() in Base nicht zugreifen. Der implementierende Code in der Klasse Derived kann aber die Implementierung in Base über super.m1() benutzen. Was die Referenzvariable derived2 angeht, ist dieser Code jedoch nicht sichtbar.

Page 36: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Mehrere Referenzen auf ein Objekt

36

Substituierbarkeit: Wir können das Derived2-Object, das an die Referenz derived2 gebunden ist, mit jeder Variablen eines Typs T referenzieren, wenn Derived2 zu T konform ist.

Die Typhierarchie ergibt, dass Derived, Base, und IType Supertypen von Derived2 sind, Derived2 also zu ihnen konform ist.

Daher kann z. B. eine Base-Referenz an das von derived2 referenzierte Objekt gebunden werden.

Base base = derived2;ergibt eine weitere Menge vonBullaugen

Page 37: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Mehrere Referenzen auf ein Objekt

37

• Es findet keine Veränderung an dem Derived2-Objekt oder seinen Operations-Abbildungen statt.

• Werden m1() oder m2(String) auf derived2 oder base aufgerufen, wird jeweils derselbe Code ausgeführt.

String tmp;

tmp = derived2.m1();    // Derived2 reference     // tmp is "Derived.m1()"

tmp = derived2.m2("Hello");// tmp is "Derived2.m2(Hello)"

tmp = base.m1();      // Base reference             // tmp is "Derived.m1()"

tmp = base.m2("Hello");        // tmp is "Derived2.m2(Hello)"

Page 38: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Mehrere Referenzen auf ein Objekt

• Warum erhält man trotz verschiedener Referenzen identisches Verhalten?

• Ein Objekt weiß nicht, wer oder was seine Methoden aufruft. – Ein Derived2-Objekt weiß nur, dass es, wenn es

aufgerufen wird, den "Marschregeln" folgen muss, die von seiner Implementierungs-Hierarchie vorgegeben sind.

• Methoden-Auswahl (method dispatch)

• Diese Regeln legen fest, dass das Derived2-Objekt für die Methode m1() den in der Klasse Derived, und für m2(String) den in Derived2 definierten Code ausführen muss. – Die vom referenzierten Objekt ausgeführte Aktion

hängt nicht vom Typ der Referenzvariablen ab.

38

Page 39: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Mehrere Referenzen auf ein Objekt

39

String tmp;// Derived2 reference tmp = derived2.m3(); // tmp is "Derived.m3()"tmp = derived2.m4(); // tmp is "Derived2.m4()"

// Base reference tmp = base.m3();   // Compile-time errortmp = base.m4();   // Compile-time error

• Es findet keine Veränderung an dem Derived2-Objekt oder seinen Operations-Abbildungen statt.

• Jedoch kann auf die Methoden m3() und m4() nicht mehr durch die Referenz base zugegriffen werden.

Page 40: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Mehrere Referenzen auf ein Objekt

40

• Das Derived2-Objekt kann immer noch Aufrufe von m3() und m4() entgegen nehmen. • Typrestriktionen, die solche Aufrufe über die Base-

Referenz verhindern, treten zur Compilezeit auf.

• Die statische Typprüfung verhält sich wie ein Schild, indem sie Interaktionen zwischen Objekten nur durch explizit deklarierte Typ-Operationen erlaubt.• Die statischen Typen der Referenzen definieren die

Grenzen der Objektinteraktion.

• Das kann generalisiert werden: wird eine Supertyp-Referenz an ein Objekt gebunden, so wird dessen Benutzung eingeschränkt.

• Warum sollte ein Entwickler sich dafür entscheiden, Objekt-Funktionalität zu verlieren?

Page 41: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Mehrere Referenzen auf ein Objekt

Diese Entscheidung wird oft unfreiwillig gefällt. Angenommen, eine Referenzvariable ref ist an ein Objekt

gebunden, dessen Klasse folgende Methodendefinition enthält:

41

public String poly1(Base base) {  return base.m1();}

Folgender Aufruf ist erlaubt, weil der Parametertyp konform ist:ref.poly1(derived2);

Durch den Methodenaufruf wird eine lokale Base-Referenz an das übergebene Objekt gebunden.

Page 42: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Mehrere Referenzen auf ein Objekt

• Vom Standpunkt des Aufrufers, der das Derived2-Objekt übergibt, führt das Binden einer Base-Referenz durch den Implementierer von poly1(Base) zu einem Verlust von Funktionalität.

• Für Implementierer sieht jedes an poly1(Base) übergebene Objekt wie ein Base-Objekt aus.

– Den Implementierer kümmert es nicht, dass mehrere Referenztypen auf dasselbe Objekt zeigen können

– Für ihn wird ein und derselbe Referenztyp an alle Objekte gebunden, die an die Methode übergeben werden.

– Dass diese Objekte möglicherweise verschiedenen Typs sind, ist zweitrangig.

– Der Implementierer erwartet nur, dass das jeweilige Objekt alle Operationen des Typs Base auf entsprechende Implementierungen abbilden kann.

42

Page 43: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Eine Referenz auf mehrere Objekte

• Interessantes polymorphes Verhalten tritt auf, wenn eine Referenzvariable nacheinander an mehrere Objekte ggf. unterschiedlichen Typs gebunden wird. – Streng genommen, meint Objekttyp genau

den durch die Klasse des Objekts definierten Typ.

43

Derived2 derived2 = new Derived2();Derived derived = new Derived();Base base = new Base();

String tmp;tmp = ref.poly1(derived2); // tmp is "Derived.m1()"tmp = ref.poly1(derived);  // tmp is "Derived.m1()"tmp = ref.poly1(base);     // tmp is "Base.m1()"

Page 44: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Eine Referenz auf mehrere Objekte

44

• Verschiedene Objekte werden durch dasselbe Bullauge betrachtet:– Das Bullauge definiert die Abbildungen, die verfügbar sein

sollten– Verschiedene Objekte haben verschiedene Abbildungen.

Page 45: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Die Macht der Polymorphie

45

• Der Code von poly1(Base) betrachtet jedes Objekt durch eine Base-Typ-Linse.

• Wird jedoch ein Derived2-Objekt übergeben, gibt die Methode ein Ergebnis zurück, das von Code in der Klasse Derived berechnet wurde!

• Werden die Klassen Base, Derived oder Derived2 später erweitert, wird poly1(Base) problemlos Objekte der neuen Klassen akzeptieren und den erwünschten Code ausführen.

• Polymorphie gestattet, dass die neuen Klassen lange nach der Implementierung von poly1(Base) hinzu kommen.

Page 46: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Die Macht der Polymorphie

Wie geht das?

• Vom typorientierten Standpunkt aus ist der eigentliche Implementierungscode referenzierter Objekte unerheblich. – Der wichtigste Aspekt der Bindung von Referenzen an

Objekte ist der, dass durch die zur Compilezeit stattfindende Typprüfung garantiert werden kann, dass das referenzierte Objekt für jede Operation des Typs eine zur Laufzeit verfügbare Implementierung besitzt.

• Polymorphie befreit den Entwickler von der Pflicht, Implementierungsdetails einzelner Objekte zu kennen, und erlaubt statt dessen, einen Entwurf allein aus einer Typ-orientierten Perspektive anzufertigen.– Darin liegt ein signifikanter Vorteil der Trennung von Typ und

Implementierung (auch genannt "Trennung von Schnittstelle und Implementierung").

46

Page 47: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Java-Schnittstellen und Polymorphie

• Java-Schnittstellen deklarieren benutzerdefinierte Typen– Entsprechend erlauben Java-Schnittstellen polymorphes

Verhalten durch den Aufbau einer Typvererbungsstruktur.

47

public String poly2(IType iType) {  return iType.m3();}

Angenommen, eine Referenzvariable ref wird an ein Objekt gebunden, dessen Klasse folgende Methode enthält:

Das Folgende illustriert polymorphes Verhalten in poly2(IType):

Derived2 derived2 = new Derived2();Separate separate = new Separate();

String tmp;tmp = ref.poly2(derived2); // tmp is "Derived.m3()"tmp = ref.poly2(separate); // tmp is "Separate.m3()"

Page 48: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Java-Schnittstellen und Polymorphie

• Vom Typ-orientierten Standpunkt aus betrachtet gibt es keinen Unterschied zwischen den Beispielen zu poly2 und poly1.

48

Page 49: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Java-Schnittstellen und Polymorphie

• Es gibt jedoch einen wichtigen Unterschied in der Implementierung:– In poly1(Base) werden durch die Base-Derived-

Derived2-Klassenvererbungskette die benötigten Subtyp-Relationen etabliert, und das Überschreiben von Methoden führt zu den korrekten Abbildungen auf Implementierungscode.

– In poly2(IType) tritt ein völlig anderes Verhalten auf. Die Klassen Derived2 und Separate teilen sich keine gemeinsame Implementierungshierarchie

• Aber: Instanzen dieser Klassen stellen polymorphes Verhalten durch eine IType-Referenz an.

49

Durch die Gruppierung von Objekten aus unterschiedlichen Implementierungshierarchien erlauben Java-Schnittstellen polymorphes Verhalten sogar in Abwesenheit gemeinsamer Implementierungen oder überschriebener Methoden.

Page 50: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Schnittstelle und Typ eines Objekts

• Was meinen wir mit der Schnittstelle eines Objekts?

• Typischerweise bezeichnet das die Menge aller öffentlichen Methoden, die in der Klassenhierarchie des Objekts definiert werden:– Die Menge aller öffentlich

verfügbaren Methoden, die auf dem Objekt aufgerufen werden können.

50

Auf dem Bild bezieht sich die Schnittstelle zum Objekt auf die mit "Derived2 Object” bezeichnete Ebene, die alle verfügbaren Methoden für das Derived2-Objekt anführt.

Page 51: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Schnittstelle und Typ eines Objekts

• Diese Definition der Objektschnittstelle führt zu einer Implementierungs-zentrischen Sichtweise– Man konzentriert sich auf die Laufzeitfähigkeiten eines

Objekts, statt auf eine Typ-orientierte Sichtweise

• Um Polymorphie zu verstehen, müssen wir das Objekt jedoch vom typorientierten Standpunkt der mit "Base Reference" bezeichneten Ebene betrachten.

• Der Typ der Referenzvariablen diktiert dem Objekt eine Schnittstelle. Eine Schnittstelle, nicht die Schnittstelle. – Gelenkt von Typkonformität, können mehrere

typorientierte Sichtweisen an ein Objekt gebunden werden.

– Es gibt keine einzeln spezifizierte Schnittstelle zu einem Objekt.

51

Page 52: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Schnittstelle und Typ eines Objekts

• Im Sinne von Typen ist die Schnittstelle zu einem Objekt die breitestmögliche Typ-orientierte Sicht darauf.– Eine an das Objekt gebundene Supertypreferenz schränkt

diese Sicht typischerweise ein.

• Das Typkonzept erfasst den Geist der Befreiung der Objektinteraktionen von Implementierungsdetails am besten.– Anstatt sich auf die Schnittstelle eines Objekts zu

beziehen, ermutigt eine typorientierte Perspektive dazu, sich auf den an das Objekt gebundenen Referenztyp zu beziehen.

– Der Referenztyp diktiert die erlaubte Interaktion mit dem Objekt.

• Denken Sie an den Typ, wenn Sie wissen wollen, was ein Objekt tun kann, im Gegensatz zu der Art und Weise, wie das Objekt es tut. 52

Page 53: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Objektschnittstelle (nochmals)• Auf Folie 30 haben sowohl das Derived2- als auch

das Separate-Objekt eine Methode m1(). – Wie soeben diskutiert, hat die Schnittstelle beider

Objekte eine Methode m1(). • Es gibt jedoch mit diesen beiden Objekten keine

Möglichkeit, die Methode m1() polymorph zu nutzen. – Es reicht nicht aus, dass jedes Objekt m1() hat. – Ein gemeinsamer Typ mit der Operation m1() muss

existieren, durch den man die Objekte sehen kann. Die Objekte sehen so aus, als würden sie sich m1() in ihren Schnittstellen teilen.

– Ohne einen gemeinsamen Supertyp ist Polymorphie in einer statisch getypten Sprache wie Java unmöglich.

• Der Grund ist, dass Subtyping in Java nicht strukturell sondern nominell definiert ist– Strukturell: „passen“ die Methodensignaturen?– Nominell: es muss zusätzlich eine explizite

Subtypdeklaration (implements/extends Klausel) geben

53

Page 54: Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. RößlingProf. Dr. M. Mühlhäuser

RBG / Telekooperation©

Grundlagen der Informatik I: T17

Schlussbemerkungen

• Das Verständnis von Subtyp-Polymorphie erfordert einen Wechsel im Denken hin zu Typen statt Implementierungen.– Typen definieren Objektgruppierungen und kontrollieren

erlaubte Objektinteraktionen. – Die hierarchische Struktur von Typvererbung ergibt die

zum Erreichen polymorphen Verhaltens nötigen Typbeziehungen.

– Typen geben an, welche Methoden ein Objekt ausführen kann; Implementierung gibt an, wie ein Objekt auf Methodenaufrufe reagiert.

– Also bestimmen Typen Verantwortlichkeiten, und Klassen implementieren sie.

• Durch eine saubere Trennung von Typ und Implementierung ergibt sich, dass die beiden einen "Tanz der Objekte" kontrollieren: Typen bestimmen erlaubte Tanzpartner, und Implementierungen die Choreographie der Tanzschritte.

54