33
Seminar Übersetzung von künstlichen Sprachen Übersetzung objektorientierter Sprachen André Christ Münster, 5. Januar 2007

Seminar Übersetzung von künstlichen Sprachen Übersetzung objektorientierter Sprachen André Christ Münster, 5. Januar 2007

Embed Size (px)

Citation preview

Page 1: Seminar Übersetzung von künstlichen Sprachen Übersetzung objektorientierter Sprachen André Christ Münster, 5. Januar 2007

Seminar Übersetzung von künstlichen Sprachen

Übersetzung objektorientierter Sprachen

André ChristMünster, 5. Januar 2007

Page 2: Seminar Übersetzung von künstlichen Sprachen Übersetzung objektorientierter Sprachen André Christ Münster, 5. Januar 2007

2 / 30

Gliederung

1. Objektorientierte Konzepte2. Übersetzung

1. Klassen und Methoden2. Vererbung3. Parametrisierung

3. Zusammenfassung & Fazit

Page 3: Seminar Übersetzung von künstlichen Sprachen Übersetzung objektorientierter Sprachen André Christ Münster, 5. Januar 2007

1. Objektorientierte Konzepte 3 / 30

Objektorientierte Programmierung

Dr. Alan Kay: „Objektorientierte Programmierung“Austausch von Nachrichten zwischen Objekten

ObjekteZustand: InstanzvariablenVerhalten: MethodenIdentität: Bei Erzeugung (Instanziierung) festgelegt (new)

NachrichtenAnfrage, eine Operation auf einem Objekt auszuführenZur Laufzeit wird „passende“ Methode ausgewählt und ausgeführtSyntax z.B.: obj.m() oder obj->m()

Page 4: Seminar Übersetzung von künstlichen Sprachen Übersetzung objektorientierter Sprachen André Christ Münster, 5. Januar 2007

1. Objektorientierte Konzepte 4 / 30

Klassen und Methoden

KlasseBeschreibt Menge von Objekten gleicher Struktur (Methoden, Instanzvariablen)Klassendefinition: Instanzvariablen und MethodenFührt neuen Datentyp ein

MethodenMögliche Operationen eines ObjektsVergleichbar mit Funktionen (Prozeduren) aus imperativen SprachenAber: Können auf Instanzvariablen ihres Objekts zugreifen (this)

public class IntStack { private int size; // Instanzvariable private int[] data; // Instanzvariable

public int pop() { // Methode return this.data[this.size – 1]; this.size--; }}

Page 5: Seminar Übersetzung von künstlichen Sprachen Übersetzung objektorientierter Sprachen André Christ Münster, 5. Januar 2007

1. Objektorientierte Konzepte 5 / 30

Vererbung

VererbungB erbt von A: Alle Instanzvariablen und Methoden einer Superklasse A in der Unterklasse B enthaltenSpezialisierung

Unterklasse kann Instanzvariablen und Methoden hinzufügenImplementierung geerbter Methoden änderbar (Signatur gleich Invariante Spezialisierung)

Einfachvererbung (1 Superklasse, V-Baum)Mehrfachvererbung (n Superklassen, V-Graph)

Teiltypregela,b Variablen der Klassen A, BZuweisung a = b gültig, falls A und B identisch oder B Unterklasse (auch indirekt) von AZugriff nur über in A definierte Schnittstelle (A-Sicht auf B)

Figur

Flaeche()

Kreis

Flaeche()

Radius()

Page 6: Seminar Übersetzung von künstlichen Sprachen Übersetzung objektorientierter Sprachen André Christ Münster, 5. Januar 2007

1. Objektorientierte Konzepte 6 / 30

Polymorphie

Polymorphie („Vielgestaltigkeit“)Variablen, Datenobjekte sowie Argument- und Rückgabewerte können mehr als einen Datentypen annehmenPrinzip nicht auf objektorientierte Sprachen beschränktPolymorphie insbesondere auch bei funktionalen Sprachen

KlassifikationSubklassen-PolymorphieParametrische-PolymorphieÜberladenCoercion

Universelle-Polymorphie

Ad hoc-Polymorphie

Nach: Strachey / Cardelli, Wegner

Page 7: Seminar Übersetzung von künstlichen Sprachen Übersetzung objektorientierter Sprachen André Christ Münster, 5. Januar 2007

1. Objektorientierte Konzepte 7 / 30

Subklassen-Polymorphie

Anwendungsfall: Plugins / FrameworksMethoden-Auswahlregel

Ein Objekt einer Unterklasse B von A kann im Superklassenkontext von A verwendet werdenMethode m wird in Unterklasse überschriebenMethode m muss auch dann ausgeführt werden, wenn das Objekt B in Variable vom Typ A vorliegt (A-Sicht auf B)

Figur

Flaeche()

Kreis

Flaeche()

public class Kreis extends Figur {…}

Kreis k = new Kreis();k.Flaeche(); // Kreis::Flaeche()

Figur f = new Kreis(); // Superklassenkontextf.Flaeche(); // Kreis::Flaeche()

Erst zur Laufzeit bestimmbar, welche Instanz die Verarbeitung einer Nachricht übernimmt

Page 8: Seminar Übersetzung von künstlichen Sprachen Übersetzung objektorientierter Sprachen André Christ Münster, 5. Januar 2007

1. Objektorientierte Konzepte 8 / 30

Parametrische-Polymorphie

Motivation: Gleiche Funktionalität für mehrere Datentypen notwendig (insb. Datenbehältern)Bisher (Unsicherer Cast / Typüberprüfung)

Generische Klasse mit formalem Parameter T

Instanziierung mit aktuellem Parameter String:

public class Stack<T> { public void push(T element) {…} public T pop() {…}}

Stack oldStack = new Stack();oldStack.push(new Integer(2));String top = (String) oldStack.pop(); // Unsafe Downcastif (oldStack.pop() instanceof String) // instanceof type check

Stack<String> stringStack = new Stack<String>();stringStack.push("Hello World");String top = stringStack.pop();

Page 9: Seminar Übersetzung von künstlichen Sprachen Übersetzung objektorientierter Sprachen André Christ Münster, 5. Januar 2007

9 / 30

Gliederung

1. Objektorientierte Konzepte2. Übersetzung

1. Klassen und Methoden2. Vererbung3. Parametrisierung

3. Zusammenfassung & Fazit

Page 10: Seminar Übersetzung von künstlichen Sprachen Übersetzung objektorientierter Sprachen André Christ Münster, 5. Januar 2007

2. Übersetzung 10 / 30

Übersetzung

Aufspaltung des ÜbersetzungprozessesAbstrakte Maschine: Zwischencode, an Quellsprache angepasstReale Maschine: Maschinencode, durch Prozessorarchitektur bestimmt (Weit verbreitet: CISC und RISC)

Abstrakte Maschine für objektorientierte SpracheProgrammspeicher (Zwischencode)Befehlsinterpreter (Ausführung des Zwischencodes)Stack (Methodeninkarnationen in Frames)Heap (u.a. Instanzen von Klassen)

Virtuelle Maschine für objektorientierte SpracheAusführungsumgebung moderner obj. Sprachen C# / JavaAusprägung einer abstrakten MaschineAusführung des Zwischencodes zur Laufzeit des Programms

Page 11: Seminar Übersetzung von künstlichen Sprachen Übersetzung objektorientierter Sprachen André Christ Münster, 5. Januar 2007

2. Übersetzung 11 / 30

Befehls-zähler

Framepointer

Register

Hilfspeicher Frame

Frame

Object 1

Object 2

...

Object n

Klassen-deskriptorKlassen-deskriptor

...

Methoden-rumpf

Methoden-rumpf

...Main()

Programmspeicher

Befehls-interpreter

Stack

Heap

ObjektInstvar 0

Instvar 1

...

Instvar n

Objekt

Objekt

...

VirtuelleMethodentabelle

Abstrakte Maschine

Befehlszähler: Zeigt auf abzuarbeitenden Befehl in MethodenrumpfFramepointer: Verweist auf den Frame (lokale Variablen einer Methode) einer Methodeninkarnation (passend zu Befehlszähler)

In Anlehung an: Bauer, Höllerer 1998

Verweis (Zeiger)

1

2

3

45

6

0

Page 12: Seminar Übersetzung von künstlichen Sprachen Übersetzung objektorientierter Sprachen André Christ Münster, 5. Januar 2007

2. Übersetzung // Klassen und Methoden 12 / 30

KlassendeskriptorMethodentabelle: Indizierte Datenstruktur mit Methodenselektoren (Namen)

Methodenselektor verweist auf entsprechenden Methodenrumpf im Methodenarray

ClassFile { // Referenz auf Superklasse u2 super_class;

// Anzahl Instanzvariablen u2 fields_count;

// Name u. Typ d. Instanzvar. field_info fields[field_count];

// Anzahl der Methoden u2 methods_count;

// Methodentabelle method_info methods[methods_count]; […]}

Klassendeskriptor

Methodenarray

Superklasse

Methoden-tabelle

# Instanz-variablen

# Methoden

Methoden-array

Methoden-Selektor 1Methoden-Selektor 2

...

Methoden-Selektor n

Methodentabelle

Methoden-rumpf 1

...

Methoden-rumpf n

Methoden-rumpf 2

In Anlehung an: Bauer, Höllerer 1998

Auszug aus Java-class Datei:Detaillierung Klassendeskriptor:

Page 13: Seminar Übersetzung von künstlichen Sprachen Übersetzung objektorientierter Sprachen André Christ Münster, 5. Januar 2007

2. Übersetzung // Klassen und Methoden 13 / 30

Übersetzung von Methoden (1)

Methodenrumpf im Wesentlichen wie Funktions- oder Prozedurrümpfe imperativer Sprachen

Variablen, Schleifen, Verzweigungen...

Objektorientierte Sprachkonstrukte (in Methoden)Senden einer Nachricht: Object.message() (auch O->m())

Zugriff auf Instanzvariable: Object.variable (auch O->v)

Selbstreferenz: this (auch self)this.message() / this.variable

Zugriff auf Superklasse: super (auch parent)super.message() / super.variable

Page 14: Seminar Übersetzung von künstlichen Sprachen Übersetzung objektorientierter Sprachen André Christ Münster, 5. Januar 2007

2. Übersetzung // Klassen und Methoden 14 / 30

Übersetzung von Methoden (2)

Realisierung der Selbstreferenz thisMethode m einer Klasse K <ret> m(<args>)Übersetzt als Funktion: <ret> Km(K this, <args>)

Nachricht m an Objekt o vom Typ K: <ret> o.m(<args>)Umgewandelt in Funktionsaufruf: <ret> Km(o, <args>)

Methodennamen -> FunktionsnamenProblem: Globaler Namensraum von FunktionenFunktionen müssen sich in ihrem Namen unterscheidenCodierungsschema: _ZN#<Klasse>#<Methode>E<Typ>* (GNU G++ 3.0)

Abbildung auf Konzept von Funktionen / Prozeduren imp. Sprachen

Stack::push(int element) _ZN5Stack4pushEiStack::push(float element) _ZN5Stack4pushEfStack::push(float comp, float imag) _ZN5Stack4pushEff

Page 15: Seminar Übersetzung von künstlichen Sprachen Übersetzung objektorientierter Sprachen André Christ Münster, 5. Januar 2007

2. Übersetzung // Vererbung 15 / 30

Methodenaufrufe

Statisches Binden (imp. Prozedur- und Funktionsaufruf)Funktionsaufruf wird zur Übersetzungszeit der Definition der Funktion zugeordnetNach Typüberprüfung von Argument- und Rückgabewerten legt Übersetzer relative Speicheradresse fest

Dynamische Bindungsregel„Überschreibt eine Klasse B eine Methode ihrer Superklasse A und wird eine Nachricht m an ein Objekt geschickt, dessen Klassenzugehörigkeit zur Übersetzungszeit nicht bekannt ist, so muss die Methodenimplementierung zur Laufzeit an das Objekt gebunden werden.“

Bauer, Höllerer 1998

Page 16: Seminar Übersetzung von künstlichen Sprachen Übersetzung objektorientierter Sprachen André Christ Münster, 5. Januar 2007

2. Übersetzung // Vererbung 16 / 30

Dynamisches Binden mittels vtable

Virtuelle Methodentabelle (vtable)In C++ auch virtuelle FunktionstabelleSog. virtuelle Methoden in Unterklassen überschreibbarEinträge in der vtable verweisen auf MethodenimplementationenSichten: Offsets in der vtable (siehe geschweifte Klammern)

Page 17: Seminar Übersetzung von künstlichen Sprachen Übersetzung objektorientierter Sprachen André Christ Münster, 5. Januar 2007

2. Übersetzung // Vererbung 17 / 30

Realisierung vtable in C++

f : Figur

virtual Flaeche()

r : Rechteck

Flaeche() 0:Rechteck::Flaeche()

vtable

1:Rechteck::Ecken()

0:Rechteck::Flaeche()

vtable

1:Rechteck::Ecken()

Ecken()

2:Quadrat::Kante()

q : Quadrat

Kante()

InstanziierungQuadrat q = new Quadrat();Objekt erhält Zeiger auf vtable seiner Klasse

Methodenaufrufq->Flaeche();In der vtable wird Adresse der Funktionsimplementation nachgeschlagenEffiziente Implementation durch Funktionszeiger in C:

Standardisierte Indezierung der vtableUmwandlung der Methodenaufrufe:q->Flaeche() (*(q->vtable[0]))()

Page 18: Seminar Übersetzung von künstlichen Sprachen Übersetzung objektorientierter Sprachen André Christ Münster, 5. Januar 2007

2. Übersetzung // Vererbung 18 / 30

0:Rechteck::Flaeche()

vtable

1:Rechteck::Ecken()

2:Quadrat::Kante()

q : Quadrat

Kante() FigurRechteck

Quadrat

Realisierung vtable in C++

Subklassen-PolymorphieQuadrat q = new Quadrat();Rechteck f = (Rechteck) q;f->Flaeche();Sicht über vtable des Objekts vom Typ Quadrat

Page 19: Seminar Übersetzung von künstlichen Sprachen Übersetzung objektorientierter Sprachen André Christ Münster, 5. Januar 2007

2. Übersetzung // Vererbung 19 / 30

Mehrfachvererbung

Diamant Problem (Auszug)Wiederholte Beerbung: Figur und Linie erhalten Methoden und Instanzvariablen die sie an Rechteck weitervererbenUneindeutigkeit wegen doppelter Methodennamen und Instanzvariablen (Skalieren())

Lösungsansatz: Echte Mehrfachvererbung vermeiden

Mehrfachvererbung nur mit Superklassen ohne Implementierungsteil (Java, C#)z.B. Java Interfaces:

f : Figur

virtual Flaeche()

r : Rechteck

Flaeche()

g : GUIObjekt

int farbtiefe

l : Linie

Int[][] Koordinaten

virtual Skalieren()

Zeichne()

virtual Zeichne()

virtual Skalieren()

public class Rechteck implements Figur, Linie { [...]} RealisierungParallelpfad

Page 20: Seminar Übersetzung von künstlichen Sprachen Übersetzung objektorientierter Sprachen André Christ Münster, 5. Januar 2007

2. Übersetzung // Parametrisierung 20 / 30

Übersetzung von Parametrisierung

Ursprung in funktionaler Sprache MLViel Gesprächsstoff bzgl. Umsetzung von Parametrisierung in objektorientierten SprachenIn C++, Java und C# nachträglich hinzugefügt

Unterschiedliche StrategienC++ TemplatesJava Generics (ab J2SE 5.0)C# Generische Klassen (ab .NET 2.0)

“Correction these early oversights in C++ was a long and painful process, creating years of havoc as compilers never quite supported the same language, books never quite gave accurate information, trainers never quite taught the right stuff, and programmers never quite knew what to think“

(Betrand Mayer 1998, Entwickler der Programmiersprache Eiffel)

Page 21: Seminar Übersetzung von künstlichen Sprachen Übersetzung objektorientierter Sprachen André Christ Münster, 5. Januar 2007

2. Übersetzung // Parametrisierung 21 / 30

Parametrisierung in C++ (1)

Generische Klassen: C++ TemplatesÜbersetzer expandiert Templates anhand aktueller ParameterFür jeden aktuellen Parameter eigene KlasseDaher: Kopierende (auch heterogene) Übersetzung

Stack<T>

void push(T item)

T pop() Stack<float>

void push(float item)

float pop()

Stack<int>

void push(int item)

int pop()

Page 22: Seminar Übersetzung von künstlichen Sprachen Übersetzung objektorientierter Sprachen André Christ Münster, 5. Januar 2007

2. Übersetzung // Parametrisierung 22 / 30

Parametrisierung in C++ (2)

Umsetzung der Methodenaufrufe durch C++ Compiler Stack<int> intStackA;Stack<int> intStackB;intStackA.push(1);intStackB.push(2);

Stack<float> floatStack;floatStack.push(1);floatStack.pop();

_ZN5StackIiE4pushEi

_ZN5StackIfE4pushEf _ZN5StackIfE3popEv

Page 23: Seminar Übersetzung von künstlichen Sprachen Übersetzung objektorientierter Sprachen André Christ Münster, 5. Januar 2007

2. Übersetzung // Parametrisierung 23 / 30

StrategieDem Übersetzungsprozess vorgeschaltete ExpansionVgl. mit Makro-Expansion durch Präprozessor in C

BewertungPerformanz Laufzeit: Parametrisierung bringt keinen Overhead mit sich – da Abbildung auf bekannte SprachkonstrukteKeine Integration in den Sprachkern – generische Klassen sind nicht Bestandteil des TypsystemsProgrammgröße wächst stark an (Redundanter Code)

Parametrisierung in C++ (3)

Page 24: Seminar Übersetzung von künstlichen Sprachen Übersetzung objektorientierter Sprachen André Christ Münster, 5. Januar 2007

2. Übersetzung // Parametrisierung 24 / 30

Parametrisierung in Java (1)

Java GenericsHervorgegangen aus Pizza-Projekt (später GJ-Projekt)Anforderung: Auf unveränderter JVM lauffähigSeit J2SE 5.0 offizieller Bestandteil

ErasureJava-Compiler überprüft Typen (aktuelle Parameter)Formale Parameter werden durch ihren Bound ersetzt und Typkonvertierungen eingefügtErgebnis: Raw Type, frei von generischen InstuktionenAuch: Homogene Übersetzung

Bound (Obere Grenze):Implizit Object: class Stack<T> {...}Explizit Number: class Stack<T extends Number> {...}

Page 25: Seminar Übersetzung von künstlichen Sprachen Übersetzung objektorientierter Sprachen André Christ Münster, 5. Januar 2007

2. Übersetzung // Parametrisierung 25 / 30

Parametrisierung in Java (2)

Beispiel Erasure Stack<T> mit Bound Object:

public class Stack<T> { public void push(T element){…} public T pop() {…}}

Stack<String> st = new Stack<String>();st.push("Hello World");String top = st.pop();

public class Stack { public void push(Object element){…} public Object pop() {…}}

Stack st = new Stack();st.push("Hello World");String top = (String) st.pop();

Generische Klasse: Raw Type (nach Erasure):

Page 26: Seminar Übersetzung von künstlichen Sprachen Übersetzung objektorientierter Sprachen André Christ Münster, 5. Januar 2007

2. Übersetzung // Parametrisierung 26 / 30

Parametrisierung in Java (3)

Probleme (u.a.)

BewertungKeine Anpassungen an JVM nötig (Prämisse an Pizza-Projekt)Overhead durch TypkonvertierungenGenerische Typen existieren zur Laufzeit nicht mehr stack instanceof Stack<Integer> nicht möglichPrimitive Typen (int, float) können keine aktuellen Parameter sein, da kein gemeinsamer Bound existiert

Stack<String> strStack = new Stack<String>();strStack.push("Test");Object tmp = strStack;Stack<Integer> intStack = (Stack<Integer>) tmp; // Unchecked cast // without type[...]Integer intVal = intStack.pop(); // CastException // later in Code

Page 27: Seminar Übersetzung von künstlichen Sprachen Übersetzung objektorientierter Sprachen André Christ Münster, 5. Januar 2007

2. Übersetzung // Parametrisierung 27 / 30

Parametrisierung in C# (1)

s1: Stack<string> s3 : Stack<object> s4 : Stack<int>

push()

pop()

...

string

push()

pop()

...

object

Code push()

Code pop()

Code push()

Code pop()

push()

pop()

...

intvtable Stack<string> vtable Stack<object> vtable Stack<int>

s2: Stack<string>

vtable Pointer

Instvar 1

...

Instvar n

vtable Pointer

Instvar 1

...

Instvar n

vtable Pointer

Instvar 1

...

Instvar n

vtable Pointer

Instvar 1

...

Instvar n

Kompatibilität generischer KlasseninstanzenDatenstrukturen und Algorithmen der aktuellen Parameter identisch

Referenztypen zueinander kompatibel (32-bit Pointer)Primitiven Datentypen untereinander und zu Referenzzypen inkompatibel

Kopie der virtuellen Methodentabelle für jede generische KlasseninstanzKompatible Klasseninstanzen verweisen auf gemeinsamen Code

Page 28: Seminar Übersetzung von künstlichen Sprachen Übersetzung objektorientierter Sprachen André Christ Münster, 5. Januar 2007

2. Übersetzung // Parametrisierung 28 / 30

Parametrisierung in C# (2)

StrategieKombination der Vorteile der heterogenen Übersetzung (C++) und der homogenen Übersetzung (Java)Bauer, Höllerer: Echte generische Übersetzung

BewertungVöllständige Integration generischer Typen in den SprachkernTypüberprüfungen auch zur Laufzeit möglichWenig Overhead zur Laufzeit da Typkonvertierungen nicht nötigZusätzliche Verwaltung von vtables (Aber: Effiziente Implementation mit vtable Dictionaries möglich)

Page 29: Seminar Übersetzung von künstlichen Sprachen Übersetzung objektorientierter Sprachen André Christ Münster, 5. Januar 2007

29 / 30

Gliederung

1. Objektorientierte Konzepte2. Übersetzung

1. Klassen und Methoden2. Vererbung3. Parametrisierung

3. Zusammenfassung & Fazit

Page 30: Seminar Übersetzung von künstlichen Sprachen Übersetzung objektorientierter Sprachen André Christ Münster, 5. Januar 2007

3. Zusammenfassung & Fazit 30 / 30

Zusammenfassung & Fazit

Grundlagen objektorientierter SprachenKlassen und ObjekteMethoden und NachrichtenPolymorphie

ÜbersetzungAbstrakte MaschineKlassen und Methoden Gemeinsamkeiten mit imp. ProzedurenVererbung echte Mehrfachvererbung wird meist vermieden Strategien zur Realisierung von Parametrisierung

Hintergrund: Diskussionen um C++ Templates und Java Generic

Tieferes Verständnis für das objektorientierte Paradigma & für die Realisierung in konkreten objektorientierten Sprachen

Page 31: Seminar Übersetzung von künstlichen Sprachen Übersetzung objektorientierter Sprachen André Christ Münster, 5. Januar 2007

Seminar Übersetzung von künstlichen Sprachen

Vielen Dank für Eure Aufmerksamkeit!

Page 32: Seminar Übersetzung von künstlichen Sprachen Übersetzung objektorientierter Sprachen André Christ Münster, 5. Januar 2007

2. Übersetzung // Vererbung 32 / 30

Realisierung Mehrfachvererbung

f : Figur

virtual Flaeche()

r : Rechteck

Flaeche()

g : GUIObjekt

int farbtiefe

l : Linie

Int[][] Koordinaten

virtual Skalieren()

Zeichne()

virtual Zeichne()

virtual Skalieren()

GUIObjekt

Figur

GUIObjekt

Linie

Rechteck

a) Vererbungsgraph (Diamant)

GUIObjekt

Figur

Linie

Rechteck

Linie

FigurLinie

Rechteck

b.1) Mehrfache Instantiierung (von GUIObjekt)

b.2) Einfache Instantiierung (von GUIObjekt)

k : Kreis

Flaeche()

Zeichne()

Figur

Rechteck

Zurück

Page 33: Seminar Übersetzung von künstlichen Sprachen Übersetzung objektorientierter Sprachen André Christ Münster, 5. Januar 2007

2. Übersetzung // Vererbung 33 / 30

Mehrfachvererbung

Beispiel:

Nachricht im Pfad: GUIObjekt <- Figur <- Rechteck Aufruf im Parallel-Pfad: GUIObjekt <- Linie <- Rechteck

Folgt Regeln der Polymorphie

Aber: Programmierer hätte erwarten können, dass GUIObjekt::Zeichne() aufgerufen wird (falls Pfad nicht offen liegt – Teamarbeit, Bibliothek)

f : Figur

virtual Flaeche()

r : Rechteck

Flaeche()

g : GUIObjekt

int farbtiefe

l : Linie

Int[][] Koordinaten

virtual Skalieren()

Zeichne()

virtual Zeichne()

virtual Skalieren()

Figur* f = new Rechteck();f->Zeichne(); // Linie::Zeichne() auf

Zurück