Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Vorwort zur 6. Auflage
1 Allgemeine Einführung in .NET
2 Grundlagen der Sprache C#
3 Das Klassendesign
4 Vererbung, Polymorphie und Interfaces
5 Delegates und Ereignisse
6 Strukturen und Enumerationen
7 Fehlerbehandlung und Debugging
8 Auflistungsklassen (Collections)
9 Generics – Generische Datentypen
10 Weitere C#-Sprachfeatures
11 LINQ
12 Arbeiten mit Dateien und Streams
13 Binäre Serialisierung
14 XML
15 Multithreading und die Task Parallel Library (TPL)
16 Einige wichtige .NET-Klassen
17 Projektmanagement und Visual Studio 2012
18 Einführung in die WPF und XAML
19 WPF-Layout-Container
20 Fenster in der WPF
21 WPF-Steuerelemente
22 Elementbindungen
23 Konzepte von WPF
24 Datenbindung
25 Weitere Möglichkeiten der Datenbindung
26 Dependency Properties
27 Ereignisse in der WPF
28 WPF-Commands
29 Benutzerdefinierte Controls
30 2D-Grafik
31 ADO.NET – Verbindungsorientierte Objekte
32 ADO.NET – Das Command-Objekt
33 ADO.NET – Der SqlDataAdapter
34 ADO.NET – Daten im lokalen Speicher
35 ADO.NET – Aktualisieren der Datenbank
36 Stark typisierte DataSets
37 Einführung in das ADO.NET Entity Framework
38 Datenabfragen des Entity Data Models (EDM)
39 Entitätsaktualisierung und Zustandsverwaltung
40 Konflikte behandeln
41 Plain Old CLR Objects (POCOs)
Stichwort

Download:
- Beispiele, ca. 62,4 MB

Jetzt Buch bestellen
Ihre Meinung?

Spacer
Visual C# 2012 von Andreas Kühnel
Das umfassende Handbuch
Buch: Visual C# 2012

Visual C# 2012
Rheinwerk Computing
1402 S., 6., aktualisierte und erweiterte Auflage 2013, geb., mit DVD
49,90 Euro, ISBN 978-3-8362-1997-6
Pfeil 3 Das Klassendesign
Pfeil 3.1 Einführung in die Objektorientierung
Pfeil 3.2 Die Klassendefinition
Pfeil 3.2.1 Klassen im Visual Studio anlegen
Pfeil 3.2.2 Das Projekt »GeometricObjectsSolution«
Pfeil 3.2.3 Die Deklaration von Objektvariablen
Pfeil 3.2.4 Zugriffsmodifizierer einer Klasse
Pfeil 3.2.5 Splitten einer Klassendefinition mit »partial«
Pfeil 3.2.6 Arbeiten mit Objektreferenzen
Pfeil 3.3 Referenz- und Wertetypen
Pfeil 3.3.1 Werte- und Referenztypen nutzen
Pfeil 3.4 Die Eigenschaften eines Objekts
Pfeil 3.4.1 Öffentliche Felder
Pfeil 3.4.2 Datenkapselung mit Eigenschaftsmethoden sicherstellen
Pfeil 3.4.3 Die Ergänzung der Klasse »Circle«
Pfeil 3.4.4 Lese- und schreibgeschützte Eigenschaften
Pfeil 3.4.5 Sichtbarkeit der Accessoren »get« und »set«
Pfeil 3.4.6 Unterstützung von Visual Studio 2012
Pfeil 3.4.7 Automatisch implementierte Eigenschaften
Pfeil 3.5 Methoden eines Objekts
Pfeil 3.5.1 Methoden mit Rückgabewert
Pfeil 3.5.2 Methoden ohne Rückgabewert
Pfeil 3.5.3 Methoden mit Parameterliste
Pfeil 3.5.4 Methodenüberladung
Pfeil 3.5.5 Variablen innerhalb einer Methode (lokale Variablen)
Pfeil 3.5.6 Referenz- und Wertparameter
Pfeil 3.5.7 Besondere Aspekte einer Parameterliste
Pfeil 3.5.8 Zugriff auf private Daten
Pfeil 3.5.9 Die Trennung von Daten und Code
Pfeil 3.5.10 Namenskonflikte mit »this« lösen
Pfeil 3.5.11 Methode oder Eigenschaft?
Pfeil 3.5.12 Umbenennen von Methoden und Eigenschaften
Pfeil 3.6 Konstruktoren
Pfeil 3.6.1 Konstruktoren bereitstellen
Pfeil 3.6.2 Die Konstruktoraufrufe
Pfeil 3.6.3 Definition von Konstruktoren
Pfeil 3.6.4 »public«- und »internal«-Konstruktoren
Pfeil 3.6.5 »private«-Konstruktoren
Pfeil 3.6.6 Konstruktorenaufrufe umleiten
Pfeil 3.6.7 Vereinfachte Objektinitialisierung
Pfeil 3.7 Der Destruktor
Pfeil 3.8 Konstanten in einer Klasse
Pfeil 3.8.1 Konstanten mit dem Schlüsselwort »const«
Pfeil 3.8.2 Schreibgeschützte Felder mit »readonly«
Pfeil 3.9 Statische Klassenkomponenten
Pfeil 3.9.1 Statische Eigenschaften
Pfeil 3.9.2 Statische Methoden
Pfeil 3.9.3 Statische Klasseninitialisierer
Pfeil 3.9.4 Statische Klassen
Pfeil 3.9.5 Statische Klasse oder Singleton-Pattern?
Pfeil 3.10 Namensräume (Namespaces)
Pfeil 3.10.1 Zugriff auf Namespaces
Pfeil 3.10.2 Die »using«-Direktive
Pfeil 3.10.3 Globaler Namespace
Pfeil 3.10.4 Vermeiden von Mehrdeutigkeiten
Pfeil 3.10.5 Namespaces festlegen
Pfeil 3.10.6 Der »::«-Operator
Pfeil 3.10.7 Unterstützung von Visual Studio 2012 bei den Namespaces
Pfeil 3.11 Stand der Klasse »Circle«

Rheinwerk Computing - Zum Seitenanfang

3.4 Die Eigenschaften eines ObjektsZur nächsten Überschrift


Rheinwerk Computing - Zum Seitenanfang

3.4.1 Öffentliche FelderZur nächsten ÜberschriftZur vorigen Überschrift

Das Objekt eines bestimmten Typs unterscheidet sich von anderen typgleichen Objekten durch seine charakterisierenden Eigenschaften. So wie sich eine Person von jeder anderen durch den Namen, die Augenfarbe, das Alter, das Geschlecht, den Wohnort und viele andere Merkmale unterscheidet, unterscheidet sich ein Circle-Objekt von anderen Circle-Objekten durch seinen Radius, vielleicht auch durch seine Position und seine Farbe.

Eigenschaften werden durch Daten beschrieben. Welche das genau sind, hängt nur von den Anforderungen ab, die an das Objekt gestellt werden. Soll ein Circle-Objekt nicht gezeichnet werden, wird die Farbe vermutlich keine Bedeutung haben. Auf diese Eigenschaft kann dann verzichtet werden.

Alle im Programm notwendigen Objekteigenschaften müssen in der Klassendefinition Berücksichtigung finden. Gespeichert werden dazu die Werte in Variablen, die in der Klasse definiert sind. Um ein Circle-Objekt durch einen Radius und seine Positionskoordinaten zu charakterisieren, müssten Sie die Klassendefinition wie folgt schreiben:

public class Circle {
public double XCoordinate;
public double YCoordinate;
public int Radius;
}

Listing 3.9 Die Klasse »Circle« mit drei Feldern

Eigenschaften sind zunächst einmal nur Variablen, die innerhalb einer Klasse definiert sind, und werden auch als Felder bezeichnet. Der Zugriffsmodifizierer, hier public, beschreibt die Sichtbarkeit. In unserem Beispiel sind die drei Eigenschaften ohne jegliche Einschränkung überall sichtbar und damit auch manipulierbar. Grundsätzlich kann der Datentyp einer Eigenschaft beliebig sein. Es kann sich um einen elementaren Datentyp wie int oder string handeln, aber durchaus auch um ein Array oder einen benutzerdefinierten Typ, also zum Beispiel um eine Klasse, die Sie selbst in Ihrem Programmcode geschrieben haben.

Felder haben immer einen konkreten Initialisierungswert, auch wenn er nicht explizit angegeben wird. Beispielsweise weisen alle Datentypen, die Zahlen beschreiben, den Startwert 0 oder 0,0 auf, Referenztypen den Wert null. Ob Sie ein Feld mit

public int Radius;

oder

public int Radius = 0;

deklarieren, ist demnach gleich. Manchmal sorgt die explizite Zuweisung eines Startwerts für eine bessere Lesbarkeit des Programmcodes.

Der Zugriff auf eine Eigenschaft ist nicht schwierig. Instanziieren Sie zuerst die Klasse, damit Sie ein Objekt haben, und geben Sie danach die Eigenschaft, getrennt durch einen Punkt von der Objektvariablen, an.

Circle kreis = new Circle();
kreis.Radius = 10;

Jetzt hat das Circle-Objekt einen Radius von 10 Einheiten. Sehr ähnlich wird auch der Wert einer Eigenschaft ausgewertet.

int value = kreis.Radius;

Die Angabe der Eigenschaft bewirkt die Rückgabe des in ihr gespeicherten Werts. Sie können ihn, wie gezeigt, einer Variablen zuweisen oder direkt verarbeiten, beispielsweise durch Ausgabe an der Konsole.

Console.WriteLine("Der Kreisradius beträgt {0}", kreis.Radius);

Rheinwerk Computing - Zum Seitenanfang

3.4.2 Datenkapselung mit Eigenschaftsmethoden sicherstellenZur nächsten ÜberschriftZur vorigen Überschrift

Analysieren Sie die Eigenschaft Radius etwas genauer, werden Sie auf Probleme stoßen, denen bisher noch keine Aufmerksamkeit geschenkt worden ist. Was ist beispielsweise, wenn mit

kreis.Radius = -12;

dem Radius eine negative Zahl übergeben wird? Sie werden mir zustimmen, dass ein negativer Wert nicht akzeptiert werden kann. Sinnvoll sind Werte, die größer oder gleich 0 sind. Was müssen wir also tun, um die Bedingung

Radius >=  0 

zu erfüllen? Theoretisch gibt es mehrere denkbare Lösungen (beispielsweise einen anscheinend passenderen Datentyp zu wählen oder eine entsprechende Eingabeüberprüfung). Diese Ansätze sind jedoch aus mehreren Gründen schlecht. Der einzig gute Ansatz ist die Überprüfung in einer Methode der Klasse selbst. Zu diesem Zweck bietet .NET uns Eigenschaftsmethoden an.

Eigenschaftsmethoden können Sie sich als Container für zwei Subroutinen mit jeweils einem eigenen Anweisungsblock vorstellen: get und set. Der get-Block wird bei der Auswertung der Eigenschaft ausgeführt, der set-Block, wenn der Eigenschaft ein Wert zugewiesen wird.

Sehen wir uns zuerst die vollständige Implementierung der Eigenschaft Radius an, die die Forderung erfüllt, die Zuweisung eines negativen Radius an ein Circle-Objekt zu verhindern und nur einen zulässigen Wert zu speichern:

public class Circle {
private int _Radius;
// Eigenschaftsmethode
public int Radius {
get {
return _Radius;
}
set {
if (value >= 0)
_Radius = value;
else
Console.Write("Unzulässiger negativer Wert.");
}
}
[...]
}

Listing 3.10 Die Eigenschaftsmethode »Radius«

Der Wert für den Radius wird weiterhin in einem Feld gespeichert. Dieses ist nun allerdings nicht mehr public definiert, sondern private. Private Member in einer Klasse sind nur innerhalb der Klasse sichtbar. In unserem konkreten Beispiel wird damit sichergestellt, dass das Feld außerhalb der Klasse Circle weder sichtbar ist noch manipuliert werden kann. Ganz allgemein wird dieses Prinzip als Datenkapselung bezeichnet.

Die Datenkapselung ist eines der Schlüsselkonzepte der objektorientierten Programmierung, zu der auch noch die später zu behandelnde Vererbung und die Polymorphie gehören.

Der Zugriff auf das Feld erfolgt ausschließlich über den set- und get-Zweig der Eigenschaftsmethode. Da die öffentliche Eigenschaftsmethode Radius lautet, musste das private Feld aus Gründen der Eindeutigkeit umbenannt werden. Üblicherweise beginnen private Felder entweder mit einem Kleinbuchstaben oder es wird der öffentliche Bezeichner herangezogen, dem ein Unterstrich vorangestellt wird, hier _Radius.

Weisen Sie der Eigenschaft Radius mit

kreis.Radius = 10;

einen Wert zu, wird in der Eigenschaftsmethode automatisch der set-Zweig ausgeführt:

set {
if (value >= 0)
_Radius = value;
else
Console.Write("Unzulässiger negativer Wert.");
}

Der zugewiesene Wert wird von einem impliziten Parameter bereitgestellt, der immer value heißt. Der Datentyp von value entspricht dem Datentyp der Eigenschaft, in unserem Beispiel ist value demnach vom Typ int. Innerhalb des set-Anweisungsblocks können Anweisungen programmiert werden, die den zu übergebenden Wert auf seine Zulässigkeit hin überprüfen. Natürlich können Sie auch beliebige andere Operationen in set codieren, beispielsweise eine Überprüfung, ob der aktuelle Benutzer überhaupt berechtigt ist, den Eigenschaftswert festzulegen.

Die Auswertung der Eigenschaft mit

int value = kreis.Radius;

führt zum Aufruf des get-Blocks innerhalb der Eigenschaftsmethode:

get {
return _Radius;
}

Meistens enthält der get-Block, ähnlich wie in unserem Beispiel, nur eine return-Anweisung, die den Inhalt des gekapselten Feldes an den Aufrufer zurückgibt. Aber selbstverständlich dürfen Sie auch an dieser Stelle beliebige zusätzliche Operationen codieren.

Üblicherweise wird das, was ich hier als Eigenschaftsmethode bezeichne, einfach nur Eigenschaft genannt. Persönlich halte ich diese Bezeichnung für nicht gelungen, weil meiner Meinung nach eine Objekteigenschaft nicht nur durch eine Methode beschrieben wird, sondern auch durch das dazugehörige Feld, das den Wert speichert.


Rheinwerk Computing - Zum Seitenanfang

3.4.3 Die Ergänzung der Klasse »Circle«Zur nächsten ÜberschriftZur vorigen Überschrift

In ähnlicher Weise, wie wir die Eigenschaft Radius implementiert haben, sollten wir auch die beiden öffentlichen Felder XCoordinate und YCoordinate durch Eigenschaftsmethoden ersetzen.

public class Circle {
// -------- Eigenschaftsmethoden ----------
private double _YCoordinate;
public double YCoordinate {
get { return _YCoordinate; }
set { _YCoordinate = value; }
}
private double _XCoordinate;
public double XCoordinate {
get { return _XCoordinate; }
set { _XCoordinate = value; }
}
private int _Radius;
public int Radius {
get { return _Radius; }
set {
if (value >= 0)
_Radius = value;
else
Console.WriteLine("Unzulässiger negativer Radius.");
}
}
}

Listing 3.11 Die Kapselung von »Radius«, »XCoordinate« und »YCoordinate«


Rheinwerk Computing - Zum Seitenanfang

3.4.4 Lese- und schreibgeschützte EigenschaftenZur nächsten ÜberschriftZur vorigen Überschrift

Es kommt häufig vor, dass eine Eigenschaft entweder schreib- oder lesegeschützt sein muss. Die Realisierung ist denkbar einfach: Sie erstellen eine schreibgeschützte Eigenschaft ohne set-Block. Eine so definierte Eigenschaft kann nur über get ausgewertet werden.

// Schreibgeschützte Eigenschaft
private int _Value;
public int Value
{
get { return _Value; }
}

Listing 3.12 Schreibgeschützte Eigenschaft

Ein Benutzer der Klasse kann einer schreibgeschützten Eigenschaft mit einer üblichen Zuweisung keinen Wert übergeben, daher muss es einen anderen Weg geben. Dieser führt in der Regel über den Aufruf einer anderen Methode der Klasse. Häufig werden die Werte gekapselter Felder von schreibgeschützten Eigenschaften bei der Initialisierung des Objekts im Konstruktor festgelegt. Soll eine Objekteigenschaft zur Laufzeit einer Anwendung lesegeschützt sein, darf die Implementierung der Eigenschaft nur den set-Block enthalten.

// Lesegeschützte Eigenschaft
private int _Value;
public int Value
{
set { _Value = value; }
}

Listing 3.13 Lesegeschützte Eigenschaft

Der Wert einer lesegeschützten Eigenschaft kann selbstverständlich durch eine andere Methode der Klasse zurückgegeben werden, die das gekapselte Feld auswertet.


Rheinwerk Computing - Zum Seitenanfang

3.4.5 Sichtbarkeit der Accessoren »get« und »set«Zur nächsten ÜberschriftZur vorigen Überschrift

Wird keine andere Angabe gemacht, entspricht die Sichtbarkeit der beiden Accessoren get und set per Vorgabe der Sichtbarkeit der Eigenschaftsmethode. Ist die Eigenschaftsmethode public definiert, sind get und set automatisch ebenfalls public. Jeder Accessor darf auch eine individuelle Sichtbarkeit aufweisen. Damit lässt sich der jeweilige Zugriff im Bedarfsfall feiner steuern.

public int Value {
internal get {
return _Value;
}
set {
_Value = value;
}
}

Listing 3.14 Zugriffsmodifizierer einer Eigenschaft

In diesem Listing ist die Eigenschaft Value öffentlich definiert. Der set-Accessor hat keinen abweichenden Zugriffsmodifizierer und ist somit wie die Eigenschaft public. Im Gegensatz dazu schränkt der Zugriffsmodifizierer internal das Auswerten der Eigenschaft auf Code ein, der sich innerhalb der Anwendung befindet, in der auch das internal-Element codiert ist.

Beabsichtigen Sie, dem get- oder set-Zweig einen Zugriffsmodifizierer anzugeben, gelten die folgenden Regeln:

  • In der Eigenschaftsmethode müssen beide Accessoren definiert sein.
  • Nur bei einem der beiden Accessoren darf ein Zugriffsmodifizierer angegeben werden, der vom Zugriffsmodifizierer der Eigenschaftsmethode abweicht.
  • Der Zugriffsmodifizierer des Accessors muss einschränkender sein als der der Eigenschaftsmethode.

In der Praxis sind individuelle Zugriffsmodifizierer bei den Accessoren allerdings selten anzutreffen.


Rheinwerk Computing - Zum Seitenanfang

3.4.6 Unterstützung von Visual Studio 2012Zur nächsten ÜberschriftZur vorigen Überschrift

Es ist etwas mühevoll, die Struktur einer Eigenschaftsmethode zu schreiben. Sie können diese Aufgabe Visual Studio 2012 übetragen, indem Sie zuerst ein öffentliches Feld deklarieren, das bereits den Bezeichner aufweist, den das spätere gekapselte Feld haben soll, beispielsweise:

public int _Radius;

Gehen Sie anschließend mit dem Eingabecursor in den Feldbezeichner oder markieren Sie den Bezeichner komplett. Öffnen Sie nun das Kontextmenü mit der rechten Maustaste, und wählen Sie Umgestalten und dann Feld kapseln (siehe Abbildung 3.3).

Abbildung

Abbildung 3.3 Feld kapseln mit Visual Studio

Nach Bestätigung wird Visual Studio die Eigenschaftsmethode mit dem set- und get-Zweig automatisch generieren. Dabei wird, in diesem Beispiel, die Eigenschaftsmethode den Bezeichner Radius haben. Gleichzeitig wird auch die Grundfunktionalität (Wertübergabe und Wertrückgabe) erzeugt.

Visual Studio unterstützt die Entwickler bei der automatischen Generierung von Programmcode noch mit einem anderen Feature: den Code-Snippets. Ich werde später in diesem Buch noch genauer auf diese Möglichkeit eingehen. Weil aber das Erstellen einer Eigenschaft mit privatem Feld und den beiden veröffentlichenden Accessoren get und set relativ mühevoll ist, hier noch ein Tipp, wie Sie das entsprechende Code-Snippet nutzen können. Geben Sie im Code-Editor einfach propfull ein, und drücken Sie dann die Tabulator-Taste. Es wird anschließend im Code-Editor das folgende Grundgerüst einer Eigenschaft erzeugt:

private int myVar;
public int MyProperty
{
get { return myVar; }
set { myVar = value; }
}

Sie müssen jetzt nur noch den passenden Datentyp und natürlich den passenden Bezeichner für die Eigenschaft eintragen.


Rheinwerk Computing - Zum Seitenanfang

3.4.7 Automatisch implementierte EigenschaftenZur vorigen Überschrift

Daten sollten grundsätzlich immer gekapselt werden. Betrachten Sie diese Aussage nicht als Option, sondern als eine feste Regel. Mit anderen Worten bedeutet das, dass Sie zur Beschreibung einer Objekteigenschaft immer ein als private deklariertes Feld anlegen und den Zugriff mit den beiden Accessoren get und set einer Eigenschaft steuern.

Nicht selten werden Objekteigenschaften benötigt, ohne dass Code in set und get notwendig ist. Ein gutes Beispiel dafür liefert die Klasse Circle, wenn wir den Bezugskoordinaten gestatten, im Rahmen des Datentyps double einen beliebigen Wert anzunehmen:

public class Circle {
[...]
private double _XCoordinate;
public double XCoordinate {
get { return _XCoordinate; }
set { _XCoordinate = value; }
}
private double _YCoordinate;
public double YCoordinate {
get { return _YCoordinate; }
set { _YCoordinate = value; }
}
}

Listing 3.15 Aktueller Stand der Klasse »Circle«

In solchen Fällen lässt sich der Programmcode reduzieren, wenn Sie das Feature der automatisch implementierten Eigenschaften benutzen. Mit dieser Spracherweiterung ist es möglich, die Eigenschaften stattdessen wie folgt zu implementieren:

public class Circle {
public double XCoordinate {get; set;}
public double YCoordinate {get; set;}
[...]
}

Listing 3.16 Automatisch implementierte Eigenschaften

Hier wird das private Feld implizit bereitgestellt, und get bzw. set erlauben keinen Programmcode. Sie dürfen einen der beiden Zweige mit einem einschränkenden Zugriffsmodifizierer ausstatten, beispielsweise wenn Sie eine schreibgeschützte Eigenschaft bereitstellen wollen. Das Weglassen eines der beiden Accessoren ist nicht erlaubt.



Ihre Meinung

Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.

<< zurück
  Zum Rheinwerk-Shop
Zum Rheinwerk-Shop: Visual C# 2012

Visual C# 2012
Jetzt Buch bestellen


 Ihre Meinung?
Wie hat Ihnen das Openbook gefallen?
Ihre Meinung

 Buchempfehlungen
Zum Rheinwerk-Shop: Professionell entwickeln mit Visual C# 2012






 Professionell
 entwickeln mit
 Visual C# 2012


Zum Rheinwerk-Shop: Windows Presentation Foundation






 Windows Presentation
 Foundation


Zum Rheinwerk-Shop: Schrödinger programmiert C++






 Schrödinger
 programmiert C++


Zum Rheinwerk-Shop: C++ Handbuch






 C++ Handbuch


Zum Rheinwerk-Shop: C/C++






 C/C++


 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und der Schweiz
InfoInfo





Copyright © Rheinwerk Verlag GmbH 2013
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das Openbook denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt.
Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de

Cookie-Einstellungen ändern