Java ist eine sehr schöne Programmiersprache. Man hat keine Pointer/Speicherverwaltung, diverse Möglichkeiten Klassen und Methoden zu abstrahieren, und so weiter. Aber wenn wir mal ehrlich sind: der Java-Entwickler hat das Rad nicht erfunden;-)
In diesem Beitrag geht es um die Abstraktion in C++. Anhand eines einfachen Beispiels zeige ich, wie man in C++ ein Interface definiert und anschließend auch implementiert. Des Weiteren erkläre ich was eine Factory ist und wofür man sie braucht.
class Figure { protected: Figure() {} public: virtual ~Figure() {} // Aufbau: // virtual Rückgabetyp nameDerFunktion(Variable1, Variable2, VariableN) = 0; // mit dem "= 0" zwingt man den Programmierer die Methode zu implementieren!!! // Sonst gibt es Fehler beim Kompilieren... virtual double getX() = 0; virtual double getY() = 0; virtual void setX(double x) = 0; virtual void setY(double y) = 0; virtual short scaleUp(int factor) = 0; virtual short scaleDown(int factor) = 0; };
class Square : public Figure { private: double x; double y; double a; double b; public: Square (double posX, double posY, double a, double b) { this->x = posX; this->y = posY; this->a = a; this->b = b; } ~Square () { } double getX() { return x; } double getY() { return y; } void setX(double x) { this->x = x; } void setY(double y) { this->y = y; } short scaleUp(int factor) { a = a * (1 + factor / 100); b = b * (1 + factor / 100); return 1; } short scaleDown(int factor) { a = a * (1 - factor / 100); b = b * (1 - factor / 100); return 1; } }; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // ANDERE IMPLEMENTIERUNG //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ class Triangle : public Figure { private: double x; double y; double a; double b; double c; public: Triangle (double posX, double posY, double a, double b, double c) { this->x = posX; this->y = posY; this->a = a; this->b = b; this->c = c; } ~Triangle () { } double getX() { return x; } double getY() { return y; } void setX(double x) { this->x = x; } void setY(double y) { this->y = y; } short scaleUp(int factor) { a = a * (1 + factor / 100); b = b * (1 + factor / 100); c = c * (1 + factor / 100); return 1; } short scaleDown(int factor) { a = a * (1 - factor / 100); b = b * (1 - factor / 100); c = c * (1 - factor / 100); return 1; } };
Abstraktionen oder Interface sind schön und gut, aber am Ende muss jemand entscheiden, welche Implementierung ausgeführt wird. Idealerweise macht das eine Factory für uns.
Man kapselt also die Initialisierung in eine Klasse / Methode und nur diese eine Klasse / Methode darf Instanzen erzeugen. Innerhalb der Factory wird anhand verschiedener Bedienungen die richtige Implementierung ausgewählt. Diese Bedienungen werden entweder von außen mitgegeben oder per Umgebungsvariable gesetzt z.B: Umgebungsvariable „test=true“ für Stub- oder Testimplementierungen, Schlüsselkennzeichen, Uhrzeit, Laufzeitumgebung, etc.
class FigureFactory { public: static Figure* getInstance (int figureKey) { Figure* pErg; switch(figureKey) { case 1: pErg = new Triangle(0.0, 0.0, 1.0, 2.0, 3.0); break; default: pErg = new Square(0.0, 0.0, 2.0, 2.0); break; } return pErg; } }; // Hauptprogramm int main(int argc, char *argv[]) { Figure* aFig = FigureFactory::getInstance(1); aFig->scaleDown(21); aFig->getX(); }
Idealerweise wären noch die Konstruktoren von Square und Triangle protected und die Factory eine Freund-Klasse, die dann diese benutzen darf – sonst könnte ja jeder kommen…
Guter Tipp zur Erweiterung des Beitrags! Danke:)
Bitte auch erweitern!