Advanced  Services Statische Daten und Methoden Back Next Up Home

Statische Daten

In unseren bisherigen Beispielen war der Datenteil eine Klasse immer objektbezogen. Jedes Objekt, das mit Hilfe eines Konstruktors angelegt wird, enthält dann diesen Datenteil als seine Eigenschaften. Manchmal sind jedoch auch Daten nützlich, die nicht objektbezogen sind, sondern klassenbezogen, also Daten, die nur ein einziges Mal pro Klasse angelegt werden. Solche Daten nennen wir in Zukunft statische Daten. Jedes Objekt der Klasse darf auf sie zugreifen, aber sie gehören zu keinem Objekt, sie gehören eben zur Klasse. Die Deklaration von statischen Daten sieht folgendermaßen aus:

public class StaticDemo
{
   // statischer Datenteil
   private static int counter ;

   // nichtstatischer Datenteil
   private String vor, nach ;

   // Konstruktoren
   // ...

   // Methoden
   // ...

}

Und so kann man sich das im Speicher vorstellen:

static2.jpg

Es gibt verschiedene Begriffe, um diesen Unterschied klarzumachen. Statt Datenteil einer Klasse spricht man auch von Membervariablen und unterscheidet dann zwischen Instanzvariablen und Klassenvariablen. Die folgende Graphik macht also zweimal dieselbe Untercheidung mit anderen Begriffen.

variable2.jpg


Statischer Konstruktor (static initializer)

Nichtstatische Daten werden pro Objekt durch einen Konstruktor initialisiert. Es liegt nahe, etwas ähnliches für statische Daten zu erwarten. Tatsächlich gibt es einen statischen Konstruktor Wie ein Konstruktor liegt er auf der obersten Ebene der Klasse, wird jedoch durch das Schlüsselwort static eingeleitet:

Im folgende Beispiel haben wir unser Beispiel um einen statischen Konstruktor ergänzt. Wie dem Kommentar zu entnehmen ist, sind Accessmodifier hier nicht erlaubt. Ein statischer Konstruktor ist also immer public. Die statische Variable count dient dazu, die Anzahl der angelegten Instanzen zu zählen.

public class Person
{
   // Membervariablen
   private static int itemCount;
   private String vorname;
   private String nachnname;
   
   // statischer Konstruktor
   //Zugriffsmodifizierer bei statischen Konstruktoren nicht zulässig
   static Person()
   {
      count = 0;
      Console.WriteLine("static constructor");
   }
   
   // Konstruktoren
   public Person() : this("", "")
   {
      Console.WriteLine("default constructor");
   }

   public Person(String n) : this("", n)
   {
      Console.WriteLine("constructor Person(String n)");
   }

   public Person(String v, String n)
   {
      Console.WriteLine("constructor Person(String v, String n)");
      count++;
      this.vorname = v;
      this.nachnname = n;
   }

   public int GetItemCount()
   {
      return itemCount;
   }

   public static int ItemCount
   {
      get { return itemCount; }
   }

   //...
}

Wann wird der statische Konstruktor abgearbeitet

Wenn Sie zu der obigen Klasse ein Demoprogramm schreiben können Sie feststellen, in welcher Reihenfolge die Konstruktoren bei der Initialisierung abgearbeitet werden.

Der statische Konstruktor wird einmal vor dem Anlegen des ersten Objekts aufgerufen. Danach nie mehr. Es gibt aber noch eine zweite Situation, in der die statischen Daten angelegt werden, ohne daß überhaupt ein Objekt existiert.


Statische Methoden und statische Daten

Jetzt, wo wir statische Daten kennengelernt haben, erscheinen die statischen Methoden in einem klareren Licht. Statische Methoden arbeiten mit statischen Daten zusammen. Statische Methoden haben Zugriff auf statische Daten, aber keinen Zugriff auf nichtstatische Daten, da diese objektbezogen sind. Daraus ergibt sich aber auch, daß statische Daten beim ersten Aufruf einer statischen Methode initialisiert sein müssen, also muß der statische Konstruktor vor dem Aufruf abgearbeitet sein. Bestätigen Sie das mit einem passenden Demoprogramm.

Ein Standardbeispiel für einen statischen Datenteil ist ein Zähler, der die Anzahl der Objekte einer Klasse zählt. Wir werden das als Übung erledigen.


Statische Properties

Auch Properties gibt es auf statischer Ebene. Die Syntax ist die gleiche wie für nichtstatische Properties. Man ergänzt lediglich das Wort static. Das folgende Beispiel legt legt eine Get-Property an. Das sich anschließende Main verwendet die Property um die interne Variable auszulesen.

public class Person
{
   // Membervariablen
   private static int itemCount;
   private String vorname;
   private String nachnname;

   // statischer Konstruktor
   //Zugriffsmodifizierer bei statischen Konstruktoren nicht zulässig
   static Person()
   {
      itemCount = 0;
      Console.WriteLine("static constructor");
   }
   // Konstruktoren
   public Person() : this("", "")
   {
      Console.WriteLine("default constructor");
   }

   public Person(String n) : this("", n)
   {
      Console.WriteLine("constructor Person(String n)");
   }

   public Person(String v, String n)
   {
      Console.WriteLine("constructor Person(String v, String n)");
      itemCount++;
      this.vorname = v;
      this.nachnname = n;
   }

   public static int ItemCount
   {
      get { return itemCount; }
   }
   //...
}
class Test
{
   static void Main(string[] args)
   {
      Person p = new Person("a", "w");
      Person p2 = new Person("y", "x");
      Console.WriteLine(Person.ItemCount);
   }
}

Zusammenfassung

Übungen

Ein Counter für die Klasse Person

Reihenfolge der Initialisierung bei Vererbung

Valid XHTML 1.0 Strict top Back Next Up Home