Programmierparadigmen DEKLARATIV Funktional Logisch IMPERATIV Prozedural Objektorientiert Einsatz der Programmierparadigmen Systemkomplexität von der Komplexität der Algorithmen dominiert deklarativ oder prozedural Systemkomplexität höher als Komplexität der einzelnen Algorithmen Objektorientierte Programmierung OOP 3
Grundidee der OOP Abbildung der Realität in Form von objektorientierten Strukturen Objekte sind Einheiten aus Eigenschaften/Attributen/Properties ( Variablen ) z.b.: Objekt=Mensch: Mein Name ist Andreas. und Methoden/Routinen ( Funktionen ) z.b.: Objekt=Mensch: Ein Mensch kann Essen. 4
Konzepte der OOP Kapselung: Zusammenfassen von Eigenschaften und Methoden Interaktion zwischen den Objekten erfolgt über wohldefinierte Schnittstellen PRO: zwingt zu strukturierterem Programmierstil Wiederverwendbarkeit von Code Stabilitätsverbesserung leichtere Wartbarkeit 5
Grundlage der OOP - Klasse Klasse = allgemeine Beschreibung der Struktur von Objekten Klasse fasst die Eigenschaften und Methoden von Objekten zusammen Klasse = Vorlage für alle davon abgeleiteten Objekte die Instanz (=konkrete Repräsentation) einer Klasse entspricht einem Objekt alle Objekte sind Instanzen einer Klasse 6
Klasse - Beispiel class Bankangestellter { float m_monatsgehalt; public: float getjahresgehalt() const { return (m_monatsgehalt * 12); } }; 7
Tipps zu Notationen empfehlenswert: Schreibweise konsistent halten Klassennamen: Groß-Schreibung bzw. CKlassenname: z.b.: Bankangestellter bzw. CBankangestellter Schnittstellen (Interfaces: in C++ durch abstrakte Klassen realisiert): IKlassenname: z.b.: IAngestellter Attribute: Kleinschreibung mit vorangestelltem m_: z.b.: m_monatsgehalt Methoden: beginnen mit kleinem Verb, weitere Wörter groß: z.b.: getjahresgehalt() 8
Zugriffsrechte Access Specifier class Name { private: int m_x; protected: int m_y; public: int m_z; }; private: erlaubt nur Elementen der eigenen Klasse den Zugriff (default) protected: auch Elemente abgeleiteter Klassen besitzen ein Zugriffsrecht public: jedes Element kann zugreifen 9
Konstruktoren 1/3 Konstruktoren sind spezielle Methoden, die definieren, wie ein Objekt zu erzeugen ist (haben keinen Rückgabewert) Konstruktorname ist gleich dem Klassennamen ein Konstruktor wird bei der Instantierung (=Erzeugung) eines Objektes automatisch aufgerufen Zwei Konstruktoren werden automatisch (implizit) erzeugt: Standard-Konstruktor (default constructor) Kopier-Konstruktor (copy constructor) 10
Konstruktoren 2/3 Standard-Konstruktor: Hat die Signatur ClassName::ClassName() Wird kein Standard-Konstruktor deklariert, so wird ein solcher Konstruktor automatisch erzeugt (der automatisch generierte Standard-Konstruktor ist immer public und hat einen leeren Methodenrumpf) Beispiel: public class Bruch { int m_zaehler; int m_nenner; }; Bruch v1; /* Aufruf des impliziten Standard-Konstruktors */ 11
Konstruktoren 3/3 Kopier-Konstruktor: Hat die Signatur ClassName::ClassName(ClassName&) Initialisiert Objekt mit anderem Objekt vom selben Typ: neues Objekt wird erzeugt, indem übergebenes Objekt kopiert wird. Wird kein Kopier-Konstruktor deklariert, so wird ein solcher Konstruktor automatisch erzeugt. Beispiel: Bruch v1; Bruch v2(v1); /* Aufruf des Kopier-Konstruktors */ Bruch v3 = v1; /* Aufruf des Kopier-Konstruktors */ aber: Bruch v4; v4 = v1; /* Kopie mittels Zuweisungsoperator!! */ 12
Destruktoren Destruktoren sind spezielle Methoden, die automatisch vor dem Löschen eines Objektes aufgerufen werden (man kann definieren, wie ein Objekt aufzuräumen ist) Destruktorname ist ~Klassennamen, z.b., ~circle Destruktoren haben keine Inputparameter und auch keinen Rückgabewert Es ist nur ein Destruktor pro Klasse erlaubt (kann nicht überladen werden, da keine Inputparameter) 13
this-zeiger jede Methode besitzt den Zeiger this, über den eine Methode auf die Adresse des Objektes zugreifen kann, über das die Methode aufgerufen wurde class Klasse { int m_wert; public: void nix() const { } Klasse() { m_wert = 10; this -> m_wert = 10; nix(); this -> nix(); } }; 14
UML 1/2 Unified Modeling Language Modellierungssprache für (objektorientierte) Programmierung Vielzahl an Diagrammtypen Klassendiagramm: Darstellung von Klassen und ihrer Beziehung zueinander 15
UML 2/2 Klassenname -private Attribute Bruch -m_zaehler: int #protected Attribute +public Attribute -m_nenner: int <<instance of>> b1 m_zaehler=3 -private Method() #protected Method() +Bruch(in z: int, in n: int) m_nenner=4 +public Method() 16
Vererbung Definition von neuen Klassen auf Basis von existierenden Klassen Eigenschaften und Methoden werden automatisch übernommen (abhängig von den gesetzten Zugriffsrechten in der Basisklasse) Erweiterungs- und Änderungsmöglichkeiten: Hinzufügen von Eigenschaften/Methoden Überschreiben von Methoden 17
Vererbung - Beispiel class Filialleiter : public Bankangestellter { float m_weihnachtsgeld; float m_urlaubsgeld; public: float getjahresgehalt() const { return (m_weihnachtsgeld+m_urlaubsgeld+bankang estellter::getjahresgehalt()); } }; 18
Überschreiben vs. Überladen von Methoden Die Signatur einer Methode besteht aus dem Methodennamen und der Parameterliste. Werden in der abgeleiteten Klasse Methoden mit gleichem Namen wie in der Basisklasse definiert: Methode wurde überschrieben, wenn die Methoden eine idente Signatur besitzen Methode wurde überladen, wenn die Methoden eine unterschiedliche Signatur besitzen 19
Beziehungen zwischen Klassen ist-ein(e)-beziehung: Ein Filialleiter ist ein Bankangestellter. ist-implementiert-mit-beziehung: bei privater Vererbung, vererbte Methoden sind in der Subklasse nicht sichtbar, müssen neu definiert werden, möglich: Einbettung hat-ein(e)-beziehung: Aufgaben werden an das eingebettete Objekt delegiert, das eingebettete Objekt übernimmt einen Teil der Aufgaben des Hauptobjekts 20
Mehrfachvererbung 1/2 eine Klasse wird von mehreren Basisklassen abgeleitet class Subklasse: public BasisA, public BasisB { }; public: Subklasse() : BasisA(), BasisB() { m_awert=10; m_bwert=20; } 21
Mehrfachvererbung 2/2 Diamanten-Problem : Klasse erbt von zwei Klassen, die dieselbe Basisklasse haben Problem: Mehrdeutigkeiten bei geerbten Attributen Lösung: virtuelle Basisklassen (Basisklasse wird in Subklasse nur einmal eingebunden) Mehrfachvererbung von Schnittstellen (interfaces) durch Vererbung von abstrakten Klassen: (Abstrakte Klassen haben mind. eine rein virtuelle Methode, d.h., Methode ohne Rumpf) 22
OO Prinzip 1: Datenabstraktion Datenabstraktion wichtig für Wartung Datenabstraktion = Kapselung + data hiding data hiding: über Zugriffsrechte regeln, was außen hin (zu anderen Objekten) sichtbar ist Definition von Schnittstellen: beschreibt, was nach außen hin sichtbar ist unterschiedliche Schnittstellen pro Objekt Datenabstraktion für unterschiedliche Sichtweisen 23
OO Prinzip 2: Klassenzusammenhalt/ Objekt-Kopplung 1/3 class coherence = Klassenzusammenhalt definiert Grad der Beziehung zwischen den Zuständigkeiten der Klassen hoch, wenn Eigenschaften und Methoden gut zusammenarbeiten und durch Klassenname gut beschrieben Klassenzusammenhalt soll hoch sein Hinweis auf gute Faktorisierung 24
OO Prinzip 2: Klassenzusammenhalt/ Objekt-Kopplung 2/3 object coupling = Objekt-Kopplung definiert Abhängigkeit der Objekte voneinander stark, wenn viele sichtbare Eigenschaften und Methoden viele Parameter in Methoden viel Nachrichtenaustausch im laufenden System Objekt-Kopplung soll schwach sein Hinweis auf gute Kapselung 25
OO Prinzip 2: Klassenzusammenhalt/ Objekt-Kopplung 3/3 Klassenzusammenhalt (class coherence) und Objektkopplung (object coupling) stehen in enger Beziehung zueinander Gutes objektorientiertes Programmdesign: hoher Klassenzusammenhalt und geringe Objektkopplung erleichtert mögliche notwendige Adaptierungen bzw. Erweiterungen Wichtig: Planung in früher Software-Entwicklungsphase 26
OO Prinzip 3: Offen-Geschlossen- Prinzip open closed principle (OCP), Robert C. Martin Code-Einheiten (z.b. Klassen) sollen offen für Erweiterungen, aber geschlossen für Veränderungen sein Es soll möglich sein, die Funktionalität einer Code-Einheit zu erweitern, ohne ihren bestehenden Code zu verändern Eine Erweiterung an anderer Stelle, die Auswirkungen auf eine Code-Einheit hat, darf keine Änderungen der Code- Einheit selbst nach sich ziehen 27
OO Prinzip 4: Ersetzbarkeitsprinzip Liskov-Substitutionsprinzip LSP, Barbara Liskov Instanzenmenge des Obertyps enthält Instanzenmenge des Untertyps. z.b.: Eine Maus ist ein Tier. U ist Untertyp von T, wenn Instanz von U überall verwendbar ist, wo Instanz von T erwartet wird. das Verhalten eines Objekts darf sich nicht verändern, wenn über einen Basisklassen-Zeiger darauf zugegriffen wird 28
OO Prinzip 5: Polymorphismus 1/3 poly viel, morphus Gestalt Vielgestaltigkeit Fähigkeit einer abgeleiteten Klasse, die Form ihrer Basisklasse anzunehmen überall dort, wo ein Objekt der Basisklasse erwartet wird, kann auch ein Objekt der abgeleiteten Klasse verwendet werden 29
OO Prinzip 5: Polymorphismus 2/3 SpielObjekt -m_x: KoordTyp -m_y: KoordTyp +getposition(): PosTyp Tuer +istoffen() 30
OO Prinzip 5: Polymorphismus 3/3 Tuer tuer(6,5,true); SpielObjekt so = tuer; SpielObjekt* pso = &tuer; cout << pso->getposition() << endl; cout << pso->istoffen() << endl; OK slicing (Weglassen der ungültigen Eigenschaften/Methoden) OK nicht OK Tuer* ptuer = pso; falsche Typzuweisung (Zeiger auf Tuer Zeiger auf Spielobjekt) Tuer* ptuer = static_cast<tuer*> (pso); cout << ptuer->istoffen() << endl; OK 31