/***************************************************************/
/* Prof. Dr. Carsten Vogt                                      */
/* FH Koeln, Fak. 07 / Nachrichtentechnik                      */
/* http://www.nt.fh-koeln.de/vogt                              */
/*                                                             */
/* Das Programm demonstriert den Unterschied zwischen klassen- */
/* bezogenen ("statischen") und objektbezogenen Attributen und */
/* Methoden.                                                   */
/***************************************************************/

import java.io.*;

class Konto {

 /* klassenbezogenes Attribut anzahlKonten:
    gibt die Anzahl existierender Konten (= Objekte der konto-Klasse) an */

 static private int anzahlKonten = 0;

 /* klassenbezogene Methode getAnzahlkonten():
    liefert Anzahl existierender Konten */

 static public int getAnzahlKonten() {
  /* Zugriff aus klassenbezogener Methode auf klassenbezogenes Attribut */
  return anzahlKonten;
 }

 /* objektbezogenes Attribut stand:
    gibt den aktuellen Kontostand in dem betreffenden Konto-Objekt an */

 private double stand;

 /* Konstruktor Konto(): setzt Anfangsstand des Konto-Objekts auf
    initBetrag und erhoeht Klassenattribut anzahlKonten um 1 */

 Konto(double stand) {
  this.stand = stand;  /* Zuweisung an Attribut des neuerzeugten Objekts */
  anzahlKonten++; /* Erhoehung des klassenbezogenen Attributs */
 } 

 /* objektbezogene Methode finalize():
    senkt bei der Loeschung des entsprechenden Objekts anzahlKonten um 1 */

 protected void finalize() {
  /* Zugriff aus objektbezogener Methode auf klassenbezogenes Attribut */
  anzahlKonten--;
  System.out.println("Konto geloescht");
  /* Zugriff aus objektbezogener Methode auf klassenbezogene Methode */
  int anz = getAnzahlKonten();
  System.out.println("Anzahl existierender Konten: " + anz);
  System.out.println();
 } 

 /* objektbezogene Methode abfragen():
    liefert aktuellen Kontostand des betreffenden Kontos */

 public double abfragen() {
  /* Zugriff aus objektbezogener Methode auf objektbezogenes Attribut */
  return stand;
 }

}

public class KlassenAttr {

 public static void main(String args[]) {

  Konto konto1, konto2; /* Objektvariablen fuer zwei Konten */

  konto1 = new Konto(100.0);

  System.out.println();
  System.out.println("Nach Erzeugung eines Objekts fuer konto1:");
  System.out.println();

  /* Aufruf einer objektbezogenen Methode */
  double std = konto1.abfragen();
  System.out.println(" Anfangsstand von konto1: " + std);

  /* Aufruf einer klassenbezogenen Methode */
  int anz = Konto.getAnzahlKonten();
  System.out.println();
  System.out.println(" Anzahl existierender Konten: " + anz);

  konto2 = new Konto(200.0);

  System.out.println();
  System.out.println("Nach Erzeugung eines Objekts fuer konto2:");
  System.out.println();
  System.out.println(" Anzahl existierender Konten: " + Konto.getAnzahlKonten());
  System.out.println();
  System.out.println();

  konto1 = null;
  System.gc();

  konto2 = null;
  System.gc();

 }

}



