Die abgeleiteten Klassen Kreis und Viereck erben die Elemente des Basisklasse und verfügen über zusätzliche Eigenschaften (Seitenlänge,

Ähnliche Dokumente
Bereits behandelt: Klassen, Konstruktoren, Destruktoren etc. Operatoren. Heute: Namensräume. Vererbung. Kompaktkurs C++ Themen F 1

Thema heute: Vererbung und Klassenhierarchien. Abgeleitete Klassen. Vererbung von Daten und Funktionen. Virtuelle Funktionen

Thema heute: Vererbung und Klassenhierarchien. Abgeleitete Klassen. Vererbung von Daten und Funktionen. Virtuelle Funktionen

Einführung in die Programmierung mit C++

Kapitel 13. Abstrakte Methoden und Interfaces. Fachgebiet Knowledge Engineering Prof. Dr. Johannes Fürnkranz

OOP und Angewandte Mathematik. Eine Einführung in die Anwendung objektorientierter Konzepte in der angewandten Mathematik

Überblick. Überblick. Abstrakte Klassen - rein virtuelle Funktionen Beispiele

Objektorientierte Programmierung mit C++ SS 2007

Polymorphismus 179. Function.h. #include <string>

Grundkurs C++ IDE Klassenhierarchien

Vererbung I. Kfz Eigenschaften und Methoden der Klasse Kfz Lkw. Pkw. Eigenschaften und Methoden der Klasse Kfz

Grundkurs C++ IDE Klassenhierarchien

Programmieren II Abstrakte Klassen / Virtuelle Methoden. Programmieren II Abstrakte Klassen / Virtuelle Methoden

Grundlagen der Informatik

virtual Wertpapier& operator=(const Wertpapier&); // VIRTUELLE ZUWEISUNG protected: static enum {wortfeldlaenge = 20}; char* name_z; double kurs; };

C++ Notnagel. Ziel, Inhalt. Programmieren in C++

11.3 Virtuelle Methoden

Objektorientiertes Programmieren mit C++ für Fortgeschrittene

Objektorientierung: Klassen und Objekte

DAP2-Programmierpraktikum Einführung in C++ (Teil 2)

Grundlagen Polymorphismus Eigenschaften virtueller Klassen Mehrfachvererbung bei ROOT. Mehrfache Vererbung. Daniel Beneckenstein. 21.

Was Mathematiker schon vor Jahrhunderten erfunden haben, gibt es jetzt endlich in ihrer Programmiersprache:

Rückblick: Benutzerdefinierte Datentypen Definition der Klasse Vektor als Container für 2-dimensionale Vektoren

HSR Rapperswil 2001 Markus Rigling. Programmieren: Vererbung. 1 Variante 2

4. Objektorientierte Programmierung mit C++

Angewandte Mathematik und Programmierung

Vorkurs C++ Programmierung

Mikrorechentechnik II. Klassen in C++

Verwendung von Klassen in C++

7. Übung Informatik II - Objektorientierte Programmierung

c) Zur Ausgabe der Transaktion soll statt print der Operator << verwendet werden.geben Sie die dazu nötigen Änderungen an.

Algorithmen zur Datenanalyse in C++

Vererbung und Polymorphie

Programmierung und Angewandte Mathematik

Überblick. Überblick zum weiteren Inhalt

Vorkurs Informatik: Erste Schritte der Programmierung mit C++

Humboldt-Universität zu Berlin Wintersemester 2010/11 Institut für Informatik Grundlagen der Programmierung. 6. Übungsblatt

Einstieg in die Informatik mit Java

Programmieren in Java

Kapitel 9. Programmierkurs. Attribute von Klassen, Methoden und Variablen. 9.1 Attribute von Klassen, Methoden und Variablen

Grundzüge der objektorientierten Programmierung

3D Programmierpraktikum: Einführung in C++ - Teil 2

Objektorientiertes Programmieren mit C++ für Fortgeschrittene

Informatik II Übung, Woche 17

Informatik I (D-MAVT)

Programmierkurs C/C++

Probeklausur: Programmierung WS04/05

3. Konzepte der objektorientierten Programmierung

Beispiel: Zwischen der Oberklasse und der abgeleiteten Klasse besteht eine ist ein Beziehung. Eine abgeleitete Klasse stellt eine Spezialisierung der

Bereits behandelt: Einfache Datentypen / Variablen. Schleifen und Verzweigungen. Funktionen. Heute: Felder, Zeiger, Referenzen. Freispeicherverwaltung

OOP und Angewandte Mathematik (Praktikum 1) Eine Einführung in die Anwendung objektorientierter Konzepte in der angewandten Mathematik

Vererbung. Gerd Bohlender. Institut für Angewandte und Numerische Mathematik. Vorlesung: Einstieg in die Informatik mit Java 23.5.

Algorithmen zur Datenanalyse in C++

Bereits behandelt: Einfache Datentypen / Variablen. Schleifen und Verzweigungen. Funktionen. Heute: Felder, Zeiger, Referenzen. Freispeicherverwaltung

C++ Teil 12. Sven Groß. 18. Jan Sven Groß (IGPM, RWTH Aachen) C++ Teil Jan / 11

Programmiervorkurs WS 2013/2014. Instanzmethoden. Termin 6

Statische und Nichtstatische Methoden Properties/ Eigenschaften

Themen. Statische Methoden inline Methoden const Methoden this Zeiger Destruktor Kopierkonstruktor Überladen von Operatoren

Vererbung, Polymorphie

C++ - Objektorientierte Programmierung Vererbung

FH D. Objektorientierte Programmierung in Java FH D FH D. Prof. Dr. Ing. André Stuhlsatz. Wiederholung: Gerüstbeispiel. Vererbungshierarchie: Typ 0

Vererbung und Polymorphie

Einstieg in die Informatik mit Java

Javakurs für Anfänger

Programmierkurs C++ Abstrakte Klassen und Methoden

5. Abstrakte Klassen. Beispiel (3) Abstrakte Klasse. Beispiel (2) Angenommen, wir wollen die folgende Klassenhierarchie implementieren:

Einführung in die Programmiersprache Java II

C++ Klassen, Vererbung. Philipp Lucas. Sebastian Hack. Wintersemester 2008/09. saarland.

Praxisorientierte Einführung in C++ Lektion: "Das Schlüsselwort explicit"

Objekte wie Hund und Katz

Prinzipien der objektorientierten Programmierung (OOP)

Kurzeinführung in C/C++ Elementare Datentypen in C++

Vererbung und Polymorphie

Einführung in C# Teil 3. Matthias Nübling

Grundlagen der Informatik Vererbung von Klassen

Abend 7 Vererbung und Polymorphie, Abstrakte Klassen

Java für Bauingenieure

Methoden und Klassen. Silke Trißl Wissensmanagement in der Bioinformatik

4. Objektorientierte Programmierung mit C++

5. Abstrakte Klassen

Vorausgesetzte Grundkenntnisse. Inhalt. Klassenhierarchie und Vererbung. Vererbung. Klassenhierarchie und Vererbung. Einführung in C# Teil 3

Lösung zur Klausur C++ und Data Mining 16. Juli 2004 (SS 2004)

Sortieren von Objekten

Silke Trißl, Prof. Ulf Leser Wissensmanagement in der Bioinformatik. Jede Applikation braucht eine Klasse mit einer main-methode

C++ - Objektorientierte Programmierung Konstruktoren und Destruktoren

Neben der Verwendung von Klassen ist Vererbung ein wichtiges Merkmal objektorientierter

Einführung in die Programmierung Wintersemester 2016/17

Programmieren in C++ Überladen von Methoden und Operatoren

13. Vererbung. Prof. Dr. François E. Cellier Informatik I für D-ITET (HS 2012)

Objektorientierte Programmierung mit C++ Vector und List

Programmierkurs C/C++

Zusammenfassung. Mit bjam und ein paar Zeilen in einem Jamroot oder Jamfile lässt sich das Kompilieren und Linken einfach automatisieren

Hydroinformatik I: Klassen

C++ Teil 5. Sven Groß. 13. Mai Sven Groß (IGPM, RWTH Aachen) C++ Teil Mai / 18

C++ - Objektorientierte Programmierung Konstante und statische Elemente

Kapitel 8 Vererbung. Korbinian Molitorisz. IPD Tichy Lehrstuhl für Programmiersysteme

Exceptions und Vererbung

const Zwei Schlüsselwörter bei der Deklaration von Variablen und Member-Funktionen haben wir noch nicht behandelt: const und static.

Programmiertechnik. Teil 4. C++ Funktionen: Prototypen Overloading Parameter. C++ Funktionen: Eigenschaften

Vererbung. Was versteht man unter dem Begriff Vererbung?

Transkript:

Kompaktkurs C++ Vererbung (inheritance) 1 Oft besitzen verschiedene Datentypen einen gemeinsamen Kern: Kreis und Viereck sind geometrische Figuren; sie haben eine Kantenzahl, eine Fläche, einen Umfang etc. Den gemeinsamen Kern kann man in einer Basisklasse Figur abbilden. Die abgeleiteten Klassen Kreis und Viereck erben die Elemente des Basisklasse und verfügen über zusätzliche Eigenschaften (Seitenlänge, Radius etc.).

Kompaktkurs C++ Beispiel: Basisklasse 2 #include <iostream> #include <cmath> class Figur protected: int Kanten_; double Flaeche_, Umfang_; public: Figur(int k, double fl, double u) : Kanten_(k), Flaeche_(fl), Umfang_(u) } }; int Kanten() const return Kanten_; } double Flaeche() const return Flaeche_; } double Umfang() const return Umfang_; } const char* Name() const return "Figur"; } std::ostream& operator << (std::ostream &os, const Figur &f) return os << "Die Figur hat " << f.kanten() << " Kanten, eine Flaeche von " << f.flaeche() << ", einen Umfang von " << f.umfang() << "\n"; }

Kompaktkurs C++ Beispiel: abgeleitete Klassen 3 class Kreis : public Figur protected: double Radius_; public: Kreis (double r) : Figur(0, M_PI*r*r, 2*M_PI*r), Radius_(r) } }; double Radius() const return Radius_; } const char* Name() const return "Kreis"; } class Viereck : public Figur protected: double Seite_[2]; public: Viereck (double s0, double s1) : Figur(4, s0*s1, 2*(s0+s1)) Seite_[0]=s0; Seite_[1]=s1; } }; double Seite(int i) const return Seite_[i]; } const char* Name() const return "Viereck"; }

Kompaktkurs C++ Beispiel: Hauptprogramm 4 int main() Figur mykreis(0, M_PI, 2*M_PI); Figur myquadrat(4,1,4); Kreis kreis(1); Viereck quadrat(1,1); std::cout << mykreis << "und ist ein(e) " << mykreis.name() << ".\n" << myquadrat << "und ist ein(e) " << myquadrat.name() << ".\n" << kreis << "und ist ein(e) " << kreis.name() << ".\n" << quadrat << "und ist ein(e) " << quadrat.name() << "." << std::endl; } return 0; Die Figur hat 0 Kanten, eine Flaeche von 3.14159, einen Umfang von 6.28319 und ist ein(e) Figur. Die Figur hat 4 Kanten, eine Flaeche von 1, einen Umfang von 4 und ist ein(e) Figur. Die Figur hat 0 Kanten, eine Flaeche von 3.14159, einen Umfang von 6.28319 und ist ein(e) Kreis. Die Figur hat 4 Kanten, eine Flaeche von 1, einen Umfang von 4 und ist ein(e) Viereck.

Kompaktkurs C++ Vererbung 5 Um eine Klasse B von einer Basisklasse A abzuleiten, verwendet man die Definition class B : public A... }; Die Basisklasse A kann in mancherlei Hinsicht als Element der abgeleiteten Klasse B aufgefasst werden. Im Konstruktor wird sie beispielsweise wie ein Element angesprochen. Die Basisklasse wird somit quasi in die abgeleitete Klasse eingebettet. Dennoch besteht ein großer Unterschied zu class C A a;... }; Klasse B kann in eine Klasse A konvertiert werden, bei C funktionert das nicht (B ist ein A, C hat ein A). Von A abgeleitete Klassen dürfen auf die protected Elemente von A zugreifen, nicht aber auf die private Elemente. Das Schlüsselwort public bei der Ableitung bewirkt, dass die Basisklasse A öffentlich ist. Damit sind alle öffentlichen Daten von A auch in B öffentlich, und jede Funktion kann B*/B& in A*/A& konvertieren. Wird stattdessen private verwendet, dann dürfen nur noch die Elementfunktionen und Friends von B die öffentlichen Daten von A benutzen, und nur diese dürfen B*/B& in A*/A& konvertieren.

Kompaktkurs C++ Vererbung 6 Vererbung kann sich über mehrere Generationen erstrecken, d. h., abgeleitete Klassen können selbst wieder als Basisklassen anderer Klassen dienen. Die Klasse Viereck, abgeleitet von Figur, könnte z. B. als Basisklasse einer Klasse Quadrat dienen. Mehrfachvererbung ist ebenfalls möglich, d. h., Klassen können von mehr als einer Basisklasse abgeleitet werden. Eine Klasse Wasserflugzeug könnte z. B. von den Klassen Boot und Flugzeug abgeleitet werden durch class Wasserflugzeug : public Boot, public Flugzeug... };

Kompaktkurs C++ Typkonvertierung zur Basisklasse 7 Leider liefert folgendes Programm nicht die erhoffte Ausgabe: void print_name (const Figur &f) std::cout << "Die Figur ist ein(e) " << f.name() << ".\n"; } int main() Figur mykreis(0, M_PI, 2*M_PI); Kreis kreis(1); Viereck quadrat(1,1); print_name(mykreis); print_name(kreis); print_name(quadrat); } return 0; Die Figur ist ein(e) Figur. Die Figur ist ein(e) Figur. Die Figur ist ein(e) Figur.

Kompaktkurs C++ Virtuelle Funktionen 8 Dass bei der abgeleiteten Klasse Kreis die eigene Funktion Name und nicht die der Basisklasse Figur aufgerufen wird, selbst wenn Kreis über const Figur& angesprochen wird, kann man durch virtuelle Funktionen erreichen. Dazu muss die Funktion Name in Figur deklariert werden als: virtual const char* Name() const; Der Übersicht wegen kann man in Kreis auch virtual hinzufügen. Die Ausgabe des Programms ist nun Die Figur ist ein(e) Figur. Die Figur ist ein(e) Kreis. Die Figur ist ein(e) Viereck. Hat eine Klasse virtuelle Funktionen, so sollte man den Destruktur ebenfalls als virtual deklarieren.

Kompaktkurs C++ Vtable 9 Dass die richtigen Funktionen aufgerufen werden, wird erreicht, indem eine Tabelle (vtable) mit den Adressen der anzusprechenden Funktionen mitgeführt wird. Da dies Speicherplatz und Rechenzeit kostet, ist dieses Verhalten nicht der Default, sondern muss durch virtual aktiviert werden. Durch explizite Angabe der Klasse kann man erzwingen, dass der Vtable übergangen wird: Figur::Name() ruft die Funktion der Basisklasse Figur auf.

Kompaktkurs C++ Abstrakte Funktionen und Klassen 10 Anstatt die Daten Flaeche_ und Umfang_ zu speichern, könnten wir sie in Flaeche() und Umfang() berechnen. Da diese Berechnung nur mit den Daten aus den abgeleiteten Klassen möglich ist, müsste man dazu Flaeche() und Umfang() zu virtuellen Funktionen machen. Für die Basisklasse alleine könnte man aber keine sinnvollen Definitionen der beiden Funktionen angeben. Durch Anhängen von =0 deklariert man daher die Funktion als abstrakt. Eine Klasse, die eine abstrakte Funktion enthält, ist selbst abstrakt. Man kann keine Instanzen einer abstrakten Klasse direkt erzeugen, da ihr Vtable nicht vollständig ist. Eine solche Klasse dient nur als Basisklasse. Eine von ihr abgeleitete Klasse ist nicht mehr abstrakt, wenn sie die fehlenden Funktionen definiert.

Kompaktkurs C++ Beispiel: Basisklasse 11 #include <iostream> #include <cmath> class Figur protected: int Kanten_; public: Figur(int k) : Kanten_(k) } virtual ~Figur() } }; int Kanten() const return Kanten_; } virtual double Flaeche() const = 0; virtual double Umfang() const = 0; virtual const char* Name() const return "Figur"; } std::ostream& operator << (std::ostream &os, const Figur &f) return os << "Die " << f.figur::name() << " " << f.name() << " hat " << f.kanten() << " Kanten, eine Flaeche von " << f.flaeche() << ", einen Umfang von " << f.umfang() << "\n"; }

Kompaktkurs C++ Beispiel: abgeleitete Klassen 12 class Kreis : public Figur protected: double Radius_; public: Kreis (double r) : Figur(0), Radius_(r) } double Radius() const return Radius_; } virtual double Flaeche() const return M_PI*Radius_*Radius_; } virtual double Umfang() const return 2*M_PI*Radius_; } virtual const char* Name() const return "Kreis"; } }; class Viereck : public Figur protected: double Seite_[2]; public: Viereck (double s0, double s1) : Figur(4) Seite_[0]=s0; Seite_[1]=s1; } double Seite(int i) const return Seite_[i]; } virtual double Flaeche() const return Seite_[0]*Seite_[1]; } virtual double Umfang() const return 2*(Seite_[0]+Seite_[1]); } virtual const char* Name() const return "Viereck"; } };

Kompaktkurs C++ Beispiel: Hauptprogramm 13 int main() Kreis kreis(1); Viereck quadrat(1,1); std::cout << kreis << quadrat; } return 0; Die Figur Kreis hat 0 Kanten, eine Flaeche von 3.14159, einen Umfang von 6.28319 Die Figur Viereck hat 4 Kanten, eine Flaeche von 1, einen Umfang von 4

Kompaktkurs C++ Konstruktoren 14 Konstruktoren können nicht virtuell sein. Im Normalfall ist das sinnvoll, da man ja erst ein Objekt haben muss, bevor man es über eine Referenz auf eine Basisklasse ansprechen kann. Beim Kopier-Konstruktor ist die Situation allerdings eine andere: Man hat bereits ein Objekt und will eine genaue Kopie davon anlegen. Spricht man das Objekt über eine Referenz auf eine Basisklasse an, dann wird leider nur der Basisteil kopiert. Hier hilft ein Trick: In der abstrakten Basisklasse deklarieren wir virtual Figur* Copy() const = 0; In den anderen Klassen (hier für Kreis) definieren wir Kreis* Copy() const return new Kreis(*this); } Die virtuelle Funktion Copy liefert jetzt einen Zeiger auf eine exakte Kopie zurück. Leider muss man diese Kopie wieder mit delete zerstören.