C++: Abstraktion, Interface und Implemenierung

Java und das Rad
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.

 

 

 

Ein Interface in C++

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;
};

 

Die Implementierung eines Interfaces

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;
   }
};

 

Das Wichtigste – die Factory

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();
}

 

Weitere Links und Quellen



Kommentar verfassen