Klassen und Objekte sind der Dreh- und Angelpunkt der OOP.
Elefant ist eine Klasse. Benjamin ist ein Objekt der Klasse Elefant. Eine Klasse ist somit eine Beschreibung von Eigenschaften und Fähigkeiten. Alle Elefanten haben gemeinsam, dass sie 4 Beine haben, 1 Rüssel und dass sie gehen, sitzen und mit dem Schwanz wackeln können. Um einen Elefant nun so zu beschreiben, erstellt man die Klasse Elefant mit den gewünschten Fähigkeiten und Eigenschaften.
Mit der Objekt Orientierten Programmierung versuchen wir die Problemstellung in konkreten und abstrakten Objekte abzubilden. Was das nun genau heißt, weiß niemand. Es gibt sehr viele Vorstellungen was OOP ist - denn OOP ist eine Art Philosophie.
Die Objekt Orientierte Programmierung zu erklären würde hier den Rahmen sprengen, deswegen verweise ich nur auf ein paar interessante Texte zu diesem Thema:
Erstmal ein kleines Code Beispiel:
class Car
{
private:
int doorCount;
int speed;
public:
Car();
~Car();
void faster();
void slower();
int getSpeed();
int getDoorCount();
}; //wichtig!!
//am ende einer klasse muss ein ; sein!!
Jetzt geht es ans Eingemachte:
private bedeutet, dass Niemand von außen auf diese Daten zugreifen kann. Damit der User der Klasse auf diese Daten zugreifen kann, müssen wir Funktionen im public Bereich zur Verfügung stellen. Dadurch haben wir verhindert, dass irgendein böser Programmierer, der unsere Klasse verwendet, unseren Variablen Werte geben kann, die ungültig sind. zB bei PS_anzahl eine negative Zahl,...
public heißt einfach: frei für alle. Hier sollten keine Variablen stehen, sondern nur Funktionen.
Wichtig ist, dass wir private Variablen aber Grundsätzlich ersteinmal nicht zugänglich machen sollten. Dann, wenn wir fertig sind mit unserer Klasse, überlegen wir, welche Daten der User denn brauchen könnte! zB Maximalgeschwindigkeit oder Anzahl der Türen, oder aktuelle Geschwindigkeit. Ob wir nun aber die aktuelle Geschwindigkeit als Prozentwert der Maximalgeschwindigkeit speichern, oder als normalen Wert, bleibt uns überlassen und hat den User unserer Klasse nicht zu interessieren. Er bekommt mit GetCurrentSpeed() die aktuelle Geschwindigkeit, mehr braucht er nicht zu wissen.
Neben private gibt es auch noch protected. protected bedeutet das Gleiche wie private - mit einer Ausnahme: abgeleitete Klassen behandeln protected Elemente als wären sie public. Deshalb sollte man protected sehr überlegt einsetzen. Mehr dazu erfahren wir aber erst später.
Wir haben 2 interessante Funktionen -> Auto() und ~Auto(). Konstruktor und Destruktor. Aus dem Namen lässt sich der Sinn ableiten! Jedesmal wenn wir eine neue Variable vom Typ Auto erstellen, wird der Konstruktor aufgerufen, um etwaige Ressourcen zu holen oder einfach nur um Werte zu setzen. Ein Konstruktor kann auch Parameter haben. Man kann ihn genau wie Funktionen auch Überladen.
Ein Destruktor kann nicht überladen werden. Eine Klasse hat immer nur einen Destruktor, welcher immer dann aufgerufen wird, wenn die Variable aufhört zu existieren.
Funktionen die einer Klasse gehören werden Methoden oder Member Funktionen genannt...
Schreiben wir nun eine kleine Automatenklasse, zB ein Kaugummiautomat
#include<iostream>
using namespace std;
class Automat
{
private:
int itemCount;
int insertedMoney;
int itemPrice;
public:
Automat(int, int);
void throwIn(int);
int getPrice();
int moneyBack();
bool pushButton();
bool isEmpty();
};
int main()
{
Automat automat(3,3);
automat.throwIn(10);
automat.moneyBack();
automat.throwIn(8);
automat.pushButton();
cin.get();
}
void Automat::throwIn(int money)
{
insertedMoney+=money;
}
int Automat::moneyBack()
{
int temp=insertedMoney;
insertedMoney=0;
return temp;
}
bool Automat::pushButton()
{
if(itemPrice>insertedMoney)
{
return false;
}
if(itemCount==0)
{
return false;
}
--itemCount;
insertedMoney-=itemPrice;
return true;
}
bool Automat::isEmpty()
{
return itemCount==0;
}
int Automat::getPrice()
{
return itemPrice;
}
Automat::Automat(int items, int price)
{
itemCount=items;
insertedMoney=0;
itemPrice=price;
}
Wie man sieht braucht man nicht Zwangsweise einen Destruktor selber schreiben. Der Compiler erstellt automatisch eine Standard-Variante, welche in den meisten Fällen aber nicht ausreicht. Denn der Standard Destruktor ruft nur für jede Member Variable den Destruktor auf. Sollte man also irgendetwas mit new angelegt haben, reicht der Standard Destruktor nicht mehr.