Lektion 77:

Eine Bankkonten-Verwaltung

Ganz so einfach ist die Vererbung nicht. Am Beispiel einer Verwaltung für Bankkonten werden die wesentlichen Details eingeführt.

class Konto
{
private:
   double kontostand;
public:
   Konto()
   {
      kontostand=0;
   };
   void einzahlen(double einzahlung)
   {
      kontostand+=einzahlung;
   };
   void auszahlen(double auszahlung)
   {
      kontostand-=auszahlung;
   };
   void anzeigen()
   {
      cout<<"Kontostand: "<<kontostand<<endl;
   };
};

TODO: ab hier bearbeiten

Es soll zwei Unterklassen von Konten geben:

  • Girokonto: Es hat einen Überziehungsrahmen und zum Jahresabschluß werden 30DM Kontoführungsgebühr eingezogen.
  • Sparkonto: Es kann nicht überzogen werden und zum Jahresabschluß werden Zinsen berechnet.
class Girokonto
{
private:
   double ueberziehungsrahmen;
public:
   Girokonto()
   {
      ueberziehungsrahmen=1000;
   };
   void anzeigen()
   {
      cout<<"Kontostand: "<<kontostand<<endl;
      cout<<"Ueberziehungsrahmen: "<<ueberziehungsrahmen <<endl;
   };
};

Der Compiler meldet die Fehlermeldung

==> error : 'kontostand' : undeclared identifier

Offensichtlich kennt die Klasse Girokonto das Attribut kontostand nicht. Das liegt daran, daß ich zwar angenommen habe, daß Girokonto von Konto erbt, aber ganz vergessen habe, es dem Compiler zu sagen.

class Girokonto:public Konto

Der Compiler meldet die Fehlermeldung

==> error : 'kontostand' : cannot access private member declared in class 'Konto'

Jetzt kennt die Klasse das Attribut. Leider darf sie nicht darauf zugreifen. Das Attribut kontostand wurde in der Klasse Konto als private deklariert. Das heißt, daß nur Methoden aus der Klasse Konto darauf zugreifen können. Um zu erlauben, daß Methoden aus den Unterklassen auch darauf zugreifen können, könnte man es einfach public machen. Doch das ist zu gefährlich, weil dann auch jede andere Funktion darauf zugreifen könnte.

void volkardKlautSichEineMillion(Konto &volkard)
{
   volkard.kontostand+=1000000;
};

Es gibt aber noch etwas zwischen private und public. Attribute und Methden, die protected deklariert werden, sind nur für die eigene Klasse und alle Unterklassen sichtbar.

class Konto
{
protected:
   double kontostand;
public:
   ...

Das folgende Programm funktioniert bereits:

void main()
{
   Konto k;
   Girokonto g;
   k.anzeigen();
   cout<<endl;

   g.anzeigen();
   cout<<endl;
};

Damit die Kontodaten hübsch zusammen mit dem Namen des Kontoinhabers angezeigt werden, wird eine eigene Funktion geschrieben.

void inhaberUndKontoAnzeigen(string inhaber,Konto kto)
{
   cout<<"Inhaber: "<<inhaber<<endl;
   kto.anzeigen();
   cout<<endl;
};
void main()
{
   Konto k;
   Girokonto g;

   inhaberUndKontoAnzeigen("Volkard",k);
   inhaberUndKontoAnzeigen("Wolfram",g);
};

Ein Probelauf des Programmes ergibt, daß es nicht wunschgemäß funktioniert. Der Überziehungsrahmen von Wolframs Konto wird nicht angezeigt.

Das liegt daran, daß die Variable kto gar keinen Überziehungsrahmen kennt. Beim Übergeben der Variablen g an die Variable kto wurde einfach alles, was ein Konto nicht hat, abgeschnitten. Dieses Abschneiden wird verhindert, indem ein Zeiger übergeben wird. Wie lang die Daten sind, auf die ein Zeiger zeigt, ist ja unerheblich.

void inhaberUndKontoAnzeigen(string inhaber,Konto *pKto)
{
   cout<<"Inhaber: "<<inhaber<<endl;
   pKto->anzeigen();
   cout<<endl;
};
void main()
{
   Konto k;
   Girokonto g;

   inhaberUndKontoAnzeigen("Volkard",&k);
   inhaberUndKontoAnzeigen("Wolfram",&g);
};

Eine recht merkwürdige Besonderheit von C++ sorgt dafür, daß es immer noch nicht geht. Doch dazu in der nächsten Lektion.



Falls Ihnen Fehler im Text auffallen oder Sie Verbesserungsvorschläge haben, dann schicken Sie mir bitte eine Mail. Ich werde mich dann sofort darum kümmern.
[aktuelle Version] [inhalt] [index]      [Fehlerkorrektur, Verbesserungsvorschlag]

© Volkard Henkel <volkard@normannia.de>, last update: 08/25/00