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

Inhaltsverzeichnis
1 Einführung
2 Grundlagen der Sprachsyntax
3 Klassendesign
4 Weitere Datentypen
5 Multithreading
6 Collections und LINQ
7 Eingabe und Ausgabe
8 Anwendungen: Struktur und Installation
9 Code erstellen und debuggen
10 Einige Basisklassen
11 Windows-Anwendungen erstellen
12 Die wichtigsten Steuerelemente
13 Tastatur- und Mausereignisse
14 MDI-Anwendungen
15 Grafiken mit GDI+
16 Drucken
17 Entwickeln von Steuerelementen
18 Programmiertechniken
19 WPF – Grundlagen
20 Layoutcontainer
21 WPF-Steuerelemente
22 Konzepte von WPF
23 Datenbankverbindung mit ADO.NET
24 Datenbankabfragen mit ADO.NET
25 DataAdapter
26 Offline mit DataSet
27 Datenbanken aktualisieren
28 Stark typisierte DataSets
A Anhang: Einige Übersichten
Stichwort

Jetzt Buch bestellen
Ihre Meinung?

Spacer
<< zurück
Visual Basic 2008 von Andreas Kuehnel, Stephan Leibbrandt
Das umfassende Handbuch
Buch: Visual Basic 2008

Visual Basic 2008
3., aktualisierte und erweiterte Auflage, geb., mit DVD
1.323 S., 49,90 Euro
Rheinwerk Computing
ISBN 978-3-8362-1171-0
Pfeil 3 Klassendesign
Pfeil 3.1 Objektorientierung
Pfeil 3.1.1 Einführung
Pfeil 3.1.2 Vorteile
Pfeil 3.1.3 Klassenimplementierung in .NET
Pfeil 3.1.4 Klassen in Visual Basic
Pfeil 3.1.5 Projekttyp »Klassenbibliothek«
Pfeil 3.1.6 Bemerkung zu den Codefragmenten
Pfeil 3.1.7 Objekte durch New
Pfeil 3.1.8 Ausnahmen mit Throw auslösen
Pfeil 3.1.9 Datentypen
Pfeil 3.1.10 Sichtbarkeit der Klasse
Pfeil 3.1.11 Aufteilung der Definition mit Partial
Pfeil 3.1.12 Grafikbibliothek: Beispiel für Kapitel 3 und 4
Pfeil 3.2 Kapselung
Pfeil 3.2.1 Kombinationen
Pfeil 3.2.2 Private
Pfeil 3.2.3 Sichtbarkeitsmodifikatoren
Pfeil 3.2.4 Lokale Variablen
Pfeil 3.2.5 Softwareschutz
Pfeil 3.2.6 Grafikbibliothek: private Größe des Rechtecks
Pfeil 3.3 Verhalten (Methoden)
Pfeil 3.3.1 Prinzip
Pfeil 3.3.2 Verlassen der Methode
Pfeil 3.3.3 Parameter
Pfeil 3.3.4 Überladung (Overloads)
Pfeil 3.3.5 Rückgabewert
Pfeil 3.3.6 Reine Deklaration mit Partial
Pfeil 3.3.7 Grafikbibliothek: Zugriffsmethoden auf die Größe des Rechtecks
Pfeil 3.4 Bindung
Pfeil 3.4.1 Klassenbindung mit Shared
Pfeil 3.4.2 Klassenkonstruktoren
Pfeil 3.4.3 Externe Funktionen
Pfeil 3.4.4 Grafikbibliothek: Rechteckübergreifendes
Pfeil 3.5 Objektinitialisierung mit Konstruktoren
Pfeil 3.5.1 Objektkonstruktoren
Pfeil 3.5.2 Nichtöffentliche Konstrukturen
Pfeil 3.5.3 Grafikbibliothek: Initialisierung des Rechtecks
Pfeil 3.6 Zustände (Felder)
Pfeil 3.6.1 Deklaration und Initialisierung
Pfeil 3.6.2 Sichtbarkeit
Pfeil 3.6.3 Konstanten: ReadOnly und Const
Pfeil 3.6.4 With
Pfeil 3.6.5 Grafikbibliothek: Konstanten des Rechtecks
Pfeil 3.7 Eigenschaften
Pfeil 3.7.1 Kontrolle beim Aufrufer
Pfeil 3.7.2 Zugriffsmethoden
Pfeil 3.7.3 Getter und Setter: Property
Pfeil 3.7.4 Indexer
Pfeil 3.7.5 Standardeigenschaft: Default
Pfeil 3.7.6 Schreibschutz und Leseschutz: ReadOnly und WriteOnly
Pfeil 3.7.7 Sichtbarkeit
Pfeil 3.7.8 Klammern
Pfeil 3.7.9 Grafikbibliothek: Eigenschaften des Rechtecks
Pfeil 3.8 Innere Klassen
Pfeil 3.8.1 Beziehung zur äußeren Klasse
Pfeil 3.8.2 Sichtbarkeit
Pfeil 3.8.3 Grafikbibliothek: Position des Rechtecks
Pfeil 3.9 Dynamisches Verhalten: Delegate und Function
Pfeil 3.9.1 Funktionszeiger: Delegates
Pfeil 3.9.2 Automatisch generierter Code
Pfeil 3.9.3 Mehrere Aktionen gleichzeitig
Pfeil 3.9.4 Asynchrone Aufrufe
Pfeil 3.9.5 Funktionsobjekte: Function (λ-Ausdrücke)
Pfeil 3.9.6 Umwandlungen
Pfeil 3.9.7 Grafikbibliothek: Vergleich von Rechtecken
Pfeil 3.10 Ereignisse
Pfeil 3.10.1 Ereignis: Event und RaiseEvent
Pfeil 3.10.2 Statische Methodenbindung WithEvents und Handles
Pfeil 3.10.3 Dynamische Methodenbindung: AddHandler und RemoveHandler
Pfeil 3.10.4 Benutzerdefinierte Ereignisse: Custom Event
Pfeil 3.10.5 Umwandlungen
Pfeil 3.10.6 Grafikbibliothek: Größenänderungen von Rechtecken überwachen
Pfeil 3.11 Benutzerdefinierte Operatoren
Pfeil 3.11.1 Prinzip
Pfeil 3.11.2 Überladung
Pfeil 3.11.3 Vergleich
Pfeil 3.11.4 Typumwandlung mit CType: Widening und Narrowing
Pfeil 3.11.5 Wahrheitswerte: IsTrue und IsFalse
Pfeil 3.11.6 Grafikbibliothek: Addition und Umwandlung von Rechtecken
Pfeil 3.12 Alle Klassenelemente
Pfeil 3.12.1 Der Namensraum My
Pfeil 3.13 Vererbung
Pfeil 3.13.1 Klassenbeziehung durch Inherits
Pfeil 3.13.2 Sichtbarkeitsmodifikatoren
Pfeil 3.13.3 Zugriff auf Eltern mit MyBase
Pfeil 3.13.4 Modifikation: Shadows und Overloads (Overrides)
Pfeil 3.13.5 Abstrakte Klassen: MustInherit und MustOverride
Pfeil 3.13.6 Spezifische Catch-Blöcke
Pfeil 3.13.7 Eigene Ausnahmen
Pfeil 3.13.8 Arrays
Pfeil 3.13.9 Grafikbibliothek: neue Vielecke
Pfeil 3.14 Polymorphie
Pfeil 3.14.1 Virtuelle Methoden: Overridable und Overrides
Pfeil 3.14.2 Unterbrechen: Overloads, Shadows und Overrides
Pfeil 3.14.3 Unterbinden: NotInheritable, NotOverridable und MyClass
Pfeil 3.14.4 Konstruktoren
Pfeil 3.14.5 Equals
Pfeil 3.14.6 ToString
Pfeil 3.14.7 Grafikbibliothek: Objektsammlungen
Pfeil 3.15 Schnittstellen: Interface und Implements
Pfeil 3.15.1 Benennungen und Parameter
Pfeil 3.15.2 Schnittstellen und Vererbung
Pfeil 3.15.3 Schnittstellenvererbung
Pfeil 3.15.4 Schnittstelle oder abstrakte Klasse?
Pfeil 3.15.5 Grafikbibliothek: Flächen
Pfeil 3.16 Lebensende eines Objekts
Pfeil 3.16.1 Garbage Collector
Pfeil 3.16.2 Destruktoren
Pfeil 3.16.3 Dispose und Using

In diesem Kapitel werden die Konzepte der Objektorientierung und deren Realisierung in Visual Basic erläutert. Dies umfasst alle Klassenelemente und die Vererbung.

3 Klassendesign


Rheinwerk Computing - Zum Seitenanfang

3.1 Objektorientierung Zur nächsten ÜberschriftZur vorigen Überschrift


Rheinwerk Computing - Zum Seitenanfang

3.1.1 Einführung Zur nächsten ÜberschriftZur vorigen Überschrift

Im letzten Kapitel haben Sie die Sprachelemente von Visual Basic kennengelernt, die auch ohne Objektorientierung verständlich sind. In diesem Abschnitt werden Sie endlich die Welt der Objekte betreten. Was hat es damit auf sich?

Am besten lassen sich Objekte in der Softwaretechnik anhand von vier ihrer grundlegenden Konzepten beschreiben:

  • Abstrakter Datentyp Nach außen ist ein Objekt durch sein Verhalten beschrieben. Die Geschichte eines Objekts, die in seinem Zustand festgehalten wird, kann dieses Verhalten beeinflussen. Alle Objekte gleichen Verhaltens sind vom gleichen Datentyp und nur durch ihren Zustand unterschieden. Nur die Abstraktion in Form einer klar definierten Schnittstelle ist von Belang, nicht die konkrete Realisierung (Implementierung).
    • Beispiel: ein Rechteck, das nach seiner Fläche befragt werden kann
    • Visual Basic: Dem Verhalten entsprechen Methoden, dem Zustand Felder.
  • Vererbung Haben verschiedene Objekttypen Gemeinsamkeiten im Verhalten oder in der Art der Zustände, wäre es ungeschickt, diese doppelt zu realisieren. Sie werden in einem Elternobjekt zusammengefasst, von dem Kindobjekte erben. Durch das Erben übernehmen sie alle Verhaltensweisen und Zustände.
    • Beispiel: Rechteck und Kreis übernehmen die Flächenauskunft von einer allgemeinen Fläche.
    • Visual Basic: Deklaration, dass geerbt wird
  • Polymorphie (Vielgestaltigkeit) Objekttypen mit Gemeinsamkeiten können unter dem allgemeinen Typ angesprochen werden und berücksichtigen trotzdem ihr spezifisches Verhalten. Dies ist besonders praktisch in Sammlungen von Objekten.
    • Beispiel: Die Flächenberechnung berücksichtigt die Form (Kreis oder Rechteck), auch wenn nur eine allgemeine Fläche angesprochen wird.
    • Visual Basic: Deklaration, dass etwas polymorph ist
  • Kapselung Programme sollten nicht direkt auf interne Details eines Objekts zugreifen können. Die Sichtbarkeitskontrolle erhöht die Übersichtlichkeit, indem sie unerwartete Änderungen eines Objektzustandes verhindert. Außerdem sorgt die Kapselung dafür, dass ein Programmteil einen anderen nur über klar definierte Schnittstellen beeinflussen kann und daher Änderungen der Implementierung keinen Einfluss auf andere Programmteile oder die sie nutzenden Objekte haben.
    • Beispiel: Die Geometrie einer Fläche kann nicht direkt geändert werden.
    • Visual Basic: Sichtbarkeitsmodifikatoren (Public, Protected, Friend, Private)

Damit nicht für jedes Objekt aller Code neu geschrieben werden muss, erlaubt Visual Basic die Definition von Vorlagen (= Klassen) für Objekte. Zum Beispiel reicht es, nur einen Bauplan zu erstellen, um viele ähnliche Autos (= konkrete Objekte) zu bauen. Er spezifiziert den Fahrzeugtyp, zum Beispiel Kombi oder Rennwagen. Dies lässt Spielraum für verschiedene Autos gleichen Typs, zum Beispiel mit verschiedenen Farben. Das konkrete Auto ist eine Instanz einer Klasse, zum Beispiel Kombi, und die Farbe des Autos ist eine Eigenschaft. Ist nicht gerade ein Airbrush-Kunstwerk auf das Auto gespritzt, reicht ein einfaches Feld zum Speichern der Farbe.


Rheinwerk Computing - Zum Seitenanfang

3.1.2 Vorteile Zur nächsten ÜberschriftZur vorigen Überschrift

  • Modularisierung: Objekte sind in sich abgeschlossene Einheiten. Dadurch lassen sie sich wie Bausteine verwenden. Der größte Baukasten ist das .NET Framework selbst. Damit wird das Zusammensetzen fertiger Bestandteile zu einem wesentlichen Teil des Programmierens.
  • Wiederverwendbarkeit: Durch eine einzige Deklaration wird die Funktionalität einer anderen Klasse durch Vererben übernommen, ohne Code selbst schreiben zu müssen.
  • Wartungsaufwand: Das Konzept des abstrakten Datentyps und die Kapselung schaffen einfach strukturierte Einheiten, die nur über klar definierte Schnittstellen benutzbar sind. Damit kann eine Klasse unabhängig von ihrer Umgebung getestet werden. Dies bedeutet einen einzelnen Test und nicht einen für jede Kombination.
  • Klassen: Die den Objekten eines Typs gemeinsame Funktionalität kann in einer einzigen Klasse zusammengefasst werden und muss nur einmalig erstellt werden.
  • Sprachunabhängigkeit: Alle Programmteile, die CLS-konform sind, lassen sich unabhängig von der Programmiersprache kombinieren.

Rheinwerk Computing - Zum Seitenanfang

3.1.3 Klassenimplementierung in .NET Zur nächsten ÜberschriftZur vorigen Überschrift

.NET und damit Visual Basic beschränkt die Konzepte der Objektorientierung an wenigen Stellen. Es ist logisch unmöglich, eine Klasse zu definieren, die von sich selbst abhängt (möglich ist das bei generischen Typen, siehe Abschnitt 4.4, »Generisches«). Um erheblichen Problemen in der Praxis aus dem Weg zu gehen, ist es nicht möglich, von mehr als einer Klasse Funktionalität zu übernehmen, nur Einfachvererbung ist erlaubt. Abgemildert wird diese Begrenzung durch die Einführung von Schnittstellen (siehe Abschnitt 3.15, »Schnittstellen: Interface und Implements«). Meiner Erfahrung nach macht die Einschränkung das Leben eines Programmierers sehr viel leichter. Polymorphie ist nicht für Verhalten und Zustände implementiert, die an die Klasse gebunden sind. Noch zwei Bemerkungen zu Namen von Datentypen:

  • Es ist unüblich, Datentypen mit einem Buchstaben wie zum Beispiel »C« bei einer Klasse zu kennzeichnen. (Ausnahme: Eine Schnittstelle sollte mit »I« beginnen.)
  • Unterstriche in Namen sollten vermieden werden, insbesondere am Namensanfang. (Einige Automatismen generieren Namen mit Unterstrichen.)

Rheinwerk Computing - Zum Seitenanfang

3.1.4 Klassen in Visual Basic Zur nächsten ÜberschriftZur vorigen Überschrift

Alle Klassen in Visual Basic folgen demselben Schema. Analog zu den bereits bekannten Modulen besteht eine Klassendefinition aus dem Rahmen (Class X und End Class) und den Klassenmitgliedern. Die beiden wichtigsten Mitglieder sind Felder und Methoden. In den einleitenden Beispielen werden alle Felder öffentlich sein, was durch die Spezifikation von Public erreicht wird (Methoden sind implizit öffentlich). Das folgende Codefragment zeigt das Schema einer Klassendefinition. In diesem Kapitel werden weitere Arten von Klassenmitgliedern und weitere Modifikatoren wie Public vorgestellt, die hier der Einfachheit halber weggelassen sind. Alle kursiv gesetzten Namen müssen Sie Ihren Erfordernissen anpassen.


Class Klassenname 
  Public Feld As Typ 
  Sub Prozedur() 
  End Sub 
End Class

Der Zugriff auf die Klassenmitglieder erfolgt über eine Punktnotation. Das folgende Codefragment zeigt die Idee des Zugriffs. Wieder können Sie alle kursiv gesetzten Namen Ihren Erfordernissen anpassen. Wie man zu dem Objekt kommt, wird weiter unten erklärt. Hier nur so viel: Es ist vom Typ Klassenname.

Objekt.Feld 
Objekt.Prozedur()

Rheinwerk Computing - Zum Seitenanfang

3.1.5 Projekttyp »Klassenbibliothek« Zur nächsten ÜberschriftZur vorigen Überschrift

Nach so vielen theoretischen Überlegungen ist es an der Zeit, eine erste konkrete Klasse zu schaffen. Wie in Abschnitt 2.4.2, »Lösungen als Hyperprojekt« beschrieben wurde, fangen wir wieder mit einer leeren Lösung namens Klassendesign an (den Speicherort wählen Sie bitte nach Ihren Erfordernissen). Dieser fügen wir eine Klassenbibliothek hinzu (siehe Abbildung 3.1). Den Dialog rufen Sie über den Menüpunkt DateiNeuProjekt im Kontextmenü der Lösung auf.

Abbildung 3.1 Klassenbibliothek

Wir ändern die generierte Klasse

Public Class Class1 
End Class

wie folgt ab und passen den Dateinamen an:


' ...\Klassendesign\Auto\Auto.vb

Option Explicit On 
Namespace Klassendesign

  Public Class Auto 
    Public Besitzer As String 
  End Class

  '... wird später ergänzt 
End Namespace

Damit haben wir ein Projekt namens Auto mit einer Datei namens Auto.vb. Die erste Zeile schaltet die Typprüfung an (siehe Abschnitt 2.5.2, »Typisierte und untypisierte Variablen (Option Strict)«). Die Definitionen kapseln wir in einem Namensraum, wie in Abschnitt 2.4.1, »Namensräume und Imports«, beschrieben wurde. In diesem Namensraum definieren wir eine Klasse Auto, die durch den Modifikator Public für alle sichtbar ist. Sie enthält ein öffentlich zugängliches Feld Besitzer vom Typ String. Die (öffentlichen) Zustandsvariablen einer Klasse werden auch Eigenschaften genannt. In Abschnitt 3.7, »Eigenschaften«, werden Sie eine besondere Art des Zugriffs auf diese Zustände kennenlernen.

Probieren wir einen ersten Start. Dazu machen wir das Projekt zum Startprojekt (Menüpunkt Als Startprojekt festlegen des Kontextmenüs des Projekts). Ein Start, wie er in Abschnitt 2.3.2, »Start und Test«, beschrieben wurde, führt nur zu einer Fehlermeldung wie in Abbildung 3.2.

Abbildung 3.2 Die Klassenbibliothek kann nicht gestartet werden.

Die Meldung gibt uns bereits Hinweise, was zu tun ist. Als Erstes erstellen wir eine Konsolenanwendung namens Autofahrer (siehe Abschnitt 2.1.2, »Der Projekttyp Konsolenanwendung«). Über ihr Kontextmenü machen wir sie zum Startprojekt. Den Dateinamen und -inhalt ändern wir wie folgt ab und setzen, wie in Abschnitt 2.4.1, »Namensräume und Imports«, beschrieben, den Einstiegspunkt in den Projekteigenschaften (gegebenenfalls muss der Anwendung vertraut werden, siehe Abschnitt 2.3.2, »Start und Test«). Der Grund für die Fehlerbehandlung in einem Try/Catch-Block (siehe Abschnitt 2.8, »Fehlerbehandlung«) wird etwas weiter unten verständlich.


'...\Klassendesign\Autofahrer\Autofahrer.vb

Option Explicit On 
Namespace Klassendesign 
  Module Autofahrer

    Sub Main() 
      ErstesAuto() 
    End Sub

    Sub ErstesAuto() 
      Dim Ente As Auto 
      Try 
        Console.WriteLine("Besitzer " & Ente.Besitzer) 
      Catch ex As Exception 
        Console.WriteLine("Problem: " & ex.Message) 
      End Try 
      Console.ReadLine() 
    End Sub

  End Module 
End Namespace

Dies ist aber noch nicht alles, denn die Entwicklungsumgebung beschwert sich darüber, dass der Typ Auto nicht bekannt ist. Um das Problem zu beheben, öffnen wir die Projekteigenschaften, zum Beispiel über das Kontextmenü des Projekts. Dort wählen wir das Register Verweise und klicken auf den Button Hinzufügen. In dem Dialog, der nach wenigen Sekunden erscheint, wählen wir, wie Abbildung 3.3 zeigt, auf der Registerkarte Projekte das Projekt Auto (der Dialog ist auch über das Kontextmenü des Projekts erreichbar).

Abbildung 3.3 Referenz hinzufügen

Schließlich sorgen wir dafür, dass der Wurzelnamensraum beider Projekte gleich ist. Er wird auf dem Register Anwendung in den Projekteigenschaften gesetzt. Abbildung 3.4 zeigt ein leeres Feld als eine Möglichkeit.

Abbildung 3.4 Leerer Wurzelnamensraum


Hinweis
Der Wurzelnamensraum muss in allen zusammenarbeitenden Projekten gleich sein oder Bezeichner müssen mit Wurzel.Namensraum.Bezeichner qualifiziert werden. Als Voreinstellung ist der Wurzelnamensraum gleich dem Projektnamen.


Je nach Ihrer Konstellation mag noch immer nicht so rechte Freude aufkommen, denn es kann noch einen weiteren Fehler geben:

Assembly '...\Klassendesign\Auto\bin\Debug\Auto.dll' must be strong signed in order to be marked as a prerequisite.

Eine Erklärung oder das Signieren der Bibliothek würde an dieser Stelle den Rahmen der Erläuterungen sprengen. Daher kümmern wir uns hier nur darum, dass die Bibliothek nicht markiert ist. Dazu klicken wir, wie Abbildung 3.5 zeigt, den Button der Anwendungsdateien auf der Registerkarte Veröffentlichen der Projekteigenschaften von Autofahrer.

Abbildung 3.5 Publizierungseinstellungen

Im nun erscheinenden (Abbildung 3.6) Dialog sorgen wir dafür, dass die Bibliothek nicht mehr als Vorraussetzung nötig ist.

Abbildung 3.6 Bibliothek einschließen

Nun wird das Ganze richtig übersetzt, gegebenenfalls über den Menüpunkt ErstellenProjektmappe neu erstellen.


Rheinwerk Computing - Zum Seitenanfang

3.1.6 Bemerkung zu den Codefragmenten Zur nächsten ÜberschriftZur vorigen Überschrift

Um die Beispiele kurz zu halten, ist häufig der Haupteinstiegspunkt weggelassen worden. Der Einstiegspunkt für das Fragment ist jeweils eine parameterlose Prozedur. Bei rein deklarativen Beispielen ist sie weggelassen.

Ein Fragment wie

Option Explicit On 
Namespace Klassendesign 
  ... 
  Module X 
    Sub Z() 
      ... 
    End Sub 
    ... 
  End Module 
End Namespace

lautet komplett:

Option Explicit On 
Namespace Klassendesign

  Module Y 
    Sub Main() 
      X.Z() 
    End Sub 
  End Module

  Module X 
    Sub Z() 
      ... 
    End Sub 
    ... 
  End Module

End Namespace

Die Ellipsen (…) werden nicht immer angegeben, und der Haupteinstiegspunkt kann sich in einer anderen Datei befinden. Die Projekte auf der Buch-DVD sind vollständig.


Rheinwerk Computing - Zum Seitenanfang

3.1.7 Objekte durch New Zur nächsten ÜberschriftZur vorigen Überschrift

Damit können wir die Anwendung starten. Die Ausgabe ist enttäuschend:

Problem: Object reference not set to an instance of an object.

Wie alle Variablen wird auch Ente durch die Deklaration Dim Ente As Auto Speicherplatz reserviert und ein Standardwert zugewiesen. Wie in Abschnitt 2.5.6, »Initialisierung von Variablen«, bereits erwähnt wurde, ist dieser Nothing. Ein Zugriff mittels »Nichts« in Ente.Besitzer (=Nothing.Besitzer) muss scheitern und erzeugt die Fehlermeldung. Der Schlüssel zur Lösung des Problems ist die Erzeugung eines Auto-Objekts, das der Variablen zugewiesen wird. In Visual Basic werden Objekte mit dem New-Operator mit folgender Syntax erzeugt (optionale Teile sind in eckige Klammern gesetzt):


New <Klassenname>([<Parameter>])

Damit können wir die Autofahrer-Datei anpassen. Im folgenden Codefragment ist auch explizit ein Besitzer angegeben. Ohne diese Zuweisung hätte das Feld Besitzer den Standardwert "" und würde sich in der Ausgabe gar nicht bemerkbar machen.


' ...\Klassendesign\Autofahrer\Autofahrer.vb

Option Explicit On 
Namespace Klassendesign 
  Module Autofahrer 
    ... 
    Sub MitBesitzer() 
      Dim Ente As Auto = New Auto() 
      Ente.Besitzer = "Kurt Knöffel" 
      Console.WriteLine("Besitzer " & Ente.Besitzer) 
      Console.ReadLine() 
    End Sub 
  End Module 
End Namespace

Es gibt noch eine abkürzende Schreibweise zur Erzeugung eines Objekts bei gleichzeitiger Deklaration und Zuweisung der Referenz an eine Variable:

Dim Ente As New Auto()

Wie bei jeder anderen Variableninitialisierung kann die Initialisierung auch in einer getrennten Zeile erfolgen (siehe Abschnitt 2.5.3, »Variablendeklaration«). Wie dort beschrieben wurde, können auch mehrere Variablen in einer Zeile deklariert werden. Dabei braucht jede Initialisierung ihre eigene As-Klausel.

Dim a1 As Auto = New Auto(), a2 As Auto = New Auto()

Hinweis
Das Erzeugen eines Objekts vom Typ X wird auch Instanziieren der Klasse X genannt.



Rheinwerk Computing - Zum Seitenanfang

3.1.8 Ausnahmen mit Throw auslösen Zur nächsten ÜberschriftZur vorigen Überschrift

Ein Spezialfall der Objekterzeugung liegt bei der Auslösung einer Ausnahme vor. Im folgenden Codefragment wird die Fläche eines Quadrats interaktiv ermittelt. Durch eine ungültige Länge wird mit Throw eine Ausnahme ausgelöst. Da Throw ein Ausnahmeobjekt erwartet, wird dieses mit New erzeugt. Ob und welche Parameter übergeben werden können, ist durch die Konstruktordefinitionen der Ausnahme festgelegt (siehe Abschnitt 3.13.7, »Eigene Ausnahmen«). Das Catch in der aufrufenden Methode fängt die Ausnahme ab und macht eine entsprechende Ausgabe:


' ...\Klassendesign\Fehlerbehandlung\Werfen.vb

Option Explicit On 
Namespace Klassendesign 
  Module Werfen

    Sub QuadratEingeben() 
      Dim a As Double 
      Console.Write("Länge: ") 
      a = Int32.Parse(Console.ReadLine()) 
      If a <= 0 Then Throw New ArgumentException() 
      Console.WriteLine("Fläche {0}.", a * a) 
    End Sub

    Sub Auffangen() 
      Try 
        QuadratEingeben() 
      Catch ex As Exception 
        Console.WriteLine("Ungültig: " & ex.Message) 
      End Try 
      Console.ReadLine() 
    End Sub

  End Module 
End Namespace

Hinweis
Throw erfordert ein Objekt von einem Typ, der auf Exception basiert. (Zur Vererbung siehe Abschnitt 3.13.1, »Klassenbeziehung durch Inherits«.)


Im Fall einer korrekten Länge erfolgt eine Protokollierung der Fläche:

Länge: 7 
Fläche 49.

Bei einer ungültigen Eingabe lautet die Ausgabe:

Länge: –2 
Ungültig: Value does not fall within the expected range.

Hinweis
Ausnahmen sollten nicht für den normalen Programmfluss verwendet werden (siehe Abschnitt 2.8, »Fehlerbehandlung«).



Rheinwerk Computing - Zum Seitenanfang

3.1.9 Datentypen Zur nächsten ÜberschriftZur vorigen Überschrift

Referenztypen: Änderungen und Mehrfachreferenzen

Die Anweisung ReferenzVariable = Objekt ist nur anscheinend eine Zuweisung eines Objekts an eine Variable. In Wirklichkeit ist der Wert der Variable nur eine Referenz auf das Objekt und nicht das Objekt selbst. Dieses ist vom System irgendwo auf dem sogenannten Heap (Haufen) abgelegt, der komplett automatisch verwaltet wird. Aus diesem Grund werden .NET-Applikationen auch verwaltete Anwendungen genannt. Alle Datentypen, die nicht direkt Werte speichern, sondern nur Verweise auf diese, werden Referenztypen genannt. Wann immer Sie mit solchen Variablen hantieren, sind nur Verweise auf die eigentlichen Daten im Spiel.

Da verschiedene Verweise auf dieselben Daten möglich sind, können dieselben Daten über verschiedene Namen erreichbar sein. Da alle solchen Variablen auf dieselben (Original-) Daten verweisen, wirken sich alle Änderungen der Daten immer auf identisch dieselben Daten aus. Über welchen der Namen die Daten geändert werden, spielt keine Rolle. Das nächste Codefragment macht dasselbe Auto über zwei Namen erreichbar.


' ...\Klassendesign\Autofahrer\Autofahrer.vb

Option Explicit On 
Namespace Klassendesign 
  Module Autofahrer 
    ... 
    Sub Synonyme() 
      Dim Ente As Auto = New Auto() 
      Dim ZweiCV As Auto = Ente 
      Ente.Besitzer = "Kurt Knöffel" 
      ZweiCV.Besitzer = "Elisa Elbers" 
      Console.WriteLine("Ente gehört " & Ente.Besitzer) 
      Console.WriteLine("ZweiCV gehört " & ZweiCV.Besitzer) 
      Console.ReadLine() 
    End Sub 
  End Module 
End Namespace

Die Ausgabe zeigt, dass der Besitzerwechsel nur einmal stattgefunden hat und dass es egal ist, ob man das Vehikel nun »Ente« oder »ZweiCV« nennt.

Ente gehört Elisa Elbers 
ZweiCV gehört Elisa Elbers

Hinweis
Verschiedene Objektreferenzen verweisen nur dann auf verschiedene Objekte, wenn diese mittels New getrennt erzeugt wurden (direkt oder innerhalb einer Funktion).


Um die Autos unabhängig voneinander zu machen, reicht es also, eine Objekterzeugung für die zweite Referenz einzufügen:

Dim Ente As Auto = New Auto() 
Dim ZweiCV As Auto = New Auto()

Hinweis
Erst, wenn es keine Referenzen mehr auf ein Objekt gibt, wird es freigegeben (zerstört). Die Änderung einer Referenz bei Mehrfachreferenzierung ändert also nichts an der Existenz des Objekts, es bleibt über die anderen Referenzen ansprechbar.


Werttypen und deren Änderung

Im Gegensatz zu den Referenztypen repräsentieren die Werttypen direkt die Daten. Beispiele für Werttypen sind alle primitiven Datentypen außer String und Object, Strukturen und Enumerationen (beide werden im nächsten Kapitel eingeführt). Werttypen werden nicht auf dem Heap gespeichert, sondern an der Stelle, an der sie verwendet werden. Bei Variablen auf Klassenebene stehen die Werte direkt im Objekt (bei Referenztypen wären es nur Verweise auf diese), während alle lokalen mit Dim gekennzeichneten Variablen einer Methode auf dem sogenannten Stack (Stapel) landen, der alle Daten und Verwaltungsinformationen aller Methoden enthält. Er wird bei Beendigung des Aufrufs automatisch aufgeräumt (vergleiche Abschnitt 2.5.5, »Sichtbarkeit und Lebensdauer«).


Hinweis
Durch das Speichern von Werttypen »vor Ort« ist bereits zur Kompilierzeit der benötigte Speicherplatz bekannt. Bei Referenztypen, die mal auf dies und dann auf jenes verweisen können, ist das erst zur Laufzeit der Fall, und die Speicherplatzreservierung ist etwas langsamer.


Damit an den entsprechenden Stellen direkt die Daten vorliegen, werden die Werttypen bei Zuweisungen oder Weitergabe an Methoden immer kopiert. Änderungen an den Daten verändern also nicht das Original. Das folgende Codefragment nutzt solche Werttypen. Die Bedeutung des Typs ist hier nicht von Belang, eigene Definitionen solcher Typen werden im nächsten Kapitel erklärt.


'...\Klassendesign\Werttypen\Werttypen.vb

Option Explicit On 
Option Compare Text 
Namespace Klassendesign 
  Module Werttypen 
    ... 
    Sub Werttypen() 
      Dim d1 As System.Collections.DictionaryEntry 
      d1.Key = "S1" : d1.Value = "V1" 
      Dim d2 As System.Collections.DictionaryEntry = d1 
      d2.Key = "S2" : d2.Value = "V2" 
      Console.WriteLine("d1 = {{{0},{1}}} ",d1.Key,d1.Value) 
      Console.WriteLine("d2 = {{{0},{1}}} ",d2.Key,d2.Value) 
      Console.ReadLine() 
    End Sub 
  End Module 
End Namespace

Die Ausgabe zeigt, dass beiden Variablen verschiedene Werte enthalten:

d1 = {S1,V1} 
d2 = {S2,V2}

Alle primitiven Datentypen sind Beispiele für Werttypen. Aber es gibt noch sehr viel mehr. In den Namensräumen, die mit den Standardeinstellungen in der Anwendung zur Verfügung stehen, sind bereits 132 Werttypen definiert (der Akzent taucht bei generischen Typen auf):

    System 
      ArgIterator, ArraySegment`1, Boolean, Byte, Char, ConsoleKeyInfo, DateTime,  
      DateTimeOffset, Decimal, Double, Enum, Guid, Int16, Int32, Int64, IntPtr,  
      ModuleHandle, Nullable`1, RuntimeArgumentHandle, RuntimeFieldHandle,  
      RuntimeMethodHandle, RuntimeTypeHandle, SByte, Single, TimeSpan,  
      TypedReference, UInt16, UInt32, UInt64, UIntPtr, Void 
    System.Threading 
      AsyncFlowControl, LockCookie, NativeOverlapped 
    System.Collections.DictionaryEntry 
    System.Collections.Generic.KeyValuePair`2 
    System.Diagnostics.SymbolStore.SymbolToken 
    System.Reflection 
      CustomAttributeNamedArgument, CustomAttributeTypedArgument,  
      InterfaceMapping, ParameterModifier 
    System.Runtime.Serialization 
      SerializationEntry, StreamingContext 
    System.Runtime.InteropServices 
      ArrayWithOffset, BIND_OPTS, BINDPTR, CONNECTDATA, DISPPARAMS, ELEMDESC,  
      EXCEPINFO, FILETIME, FUNCDESC, GCHandle, HandleRef, IDLDESC, PARAMDESC,  
      STATSTG, TYPEATTR, TYPEDESC, TYPELIBATTR, VARDESC 
    System.Runtime.InteropServices.ComTypes 
      BIND_OPTS, BINDPTR, CONNECTDATA, DISPPARAMS, ELEMDESC, EXCEPINFO, FILETIME,  
      FORMATETC, FUNCDESC, IDLDESC, PARAMDESC, STATDATA, STATSTG, STGMEDIUM,  
      TYPEATTR, TYPEDESC, TYPELIBATTR, VARDESC 
    System.Reflection.Emit 
      EventToken, FieldToken, Label, MethodToken, OpCode, ParameterToken,  
      PropertyToken, SignatureToken, StringToken, TypeToken 
    System.Configuration.Assemblies.AssemblyHash 
    System.Security.Cryptography 
      CngProperty, DSAParameters, RSAParameters 
    System.Windows.Forms 
      BindingMemberInfo, DataGridCell, LinkArea, Message, Padding,  
      TableLayoutPanelCellPosition 
    System.Windows.Forms.VisualStyles.TextMetrics 
    System.ComponentModel.Design.Serialization 
      MemberRelationship 
    System.Collections.Specialized.BitVector32 
    System.Security.Cryptography.X509Certificates 
      X509ChainStatus 
    System.Net.Sockets 
      IPPacketInformation, SocketInformation 
    System.IO.WaitForChangedResult 
    System.Diagnostics.CounterSample 
    System.Drawing 
      CharacterRange, Color, Point, PointF, Rectangle, RectangleF, Size, SizeF 
    System.Data.SqlTypes 
      SqlBinary, SqlBoolean, SqlByte, SqlDateTime, SqlDecimal, SqlDouble,  
      SqlGuid, SqlInt16, SqlInt32, SqlInt64, SqlMoney, SqlSingle, SqlString 
    System.Xml.Serialization.XmlDeserializationEvents 
    System.Diagnostics.Eventing.EventDescriptor 
    Microsoft.VisualBasic 
      SpcInfo, TabInfo

Zusammenfassend lassen sich alle Datentypen in zwei Gruppen einteilen:

  • Referenztyp Der Referenztyp ist ein Zeiger auf die Daten.
  • Werttyp Der Werttyp enthält die Daten selbst.

Gleichheit

Der Vergleich zweier Variablen kann auf zwei Arten erfolgen:

  • Identität: Ein Vergleich auf Identität prüft, ob beide dieselben Daten repräsentieren (ReferenceEquals-Methode oder Operatoren Is und IsNot).
  • Gleichheit: Ein Vergleich auf Gleichheit prüft, ob beide Variablen gleichwertig sind (Equals-Methode oder Operatoren = und <>).

Nur Referenztypen können Daten repräsentieren, Werttypen sind keine Repräsentanten, sondern halten die Daten selbst. Daher können nur Referenztypen auf Identität getestet werden. Das folgende Codefragment zeigt einen solchen Vergleich, der mit dem Is-Operator durchgeführt wird.


'...\Klassendesign\Autofahrer\Autofahrer.vb

Option Explicit On 
Namespace Klassendesign 
  Module Autofahrer 
    ... 
    Sub Identisch() 
      Dim Ente As Auto = New Auto() 
      Dim ZweiCV As Auto = Ente 
      Console.WriteLine("ZweiCV = Ente " & (ZweiCV Is Ente)) 
      Ente = New Auto() 
      Console.WriteLine("ZweiCV = Ente " & (ZweiCV Is Ente)) 
      Console.ReadLine() 
    End Sub 
  End Module 
End Namespace

Die Ausgabe zeigt, dass die Neuerzeugung des Ente-Objekts die Identität zerstört hat:

ZweiCV = Ente True 
ZweiCV = Ente False

Ein weiterer, oft gebrauchter Test ist der auf eine Nullreferenz. Dazu wird statt eines Vergleichsobjekts der Wert Nothing verwendet:


'...\Klassendesign\Autofahrer\Autofahrer.vb

Option Explicit On 
Namespace Klassendesign 
  Module Autofahrer 
    ... 
    Sub Null() 
      Dim Ente As Auto 
      Console.WriteLine("Ente uninitialisiert " & (Ente Is Nothing)) 
      Console.WriteLine("Ente initialisiert " & (Ente IsNot Nothing)) 
      Console.ReadLine() 
    End Sub 
  End Module 
End Namespace

Beide Ausgaben zeigen die fehlende Initialisierung:

Ente uninitialisiert True 
Ente initialisiert False

Für den Vergleich auf Gleichwertigkeit kommt als Erstes der Operator = in Frage. Er darf bei den primitiven Datentypen (siehe Abschnitt 2.5.4, »Einfache Datentypen«) sowie bei allen Typen verwendet werden , die den Operator definieren (siehe Abschnitt 3.11, »Benutzerdefinierte Operatoren«). Das folgende Codefragment nutzt den Operator zum Vergleich:


'...\Klassendesign\Werttypen\Werttypen.vb

Option Explicit On 
Option Compare Text 
Namespace Klassendesign 
  Module Werttypen 
    ... 
    Sub PrimitivVergleich() 
      Dim z1 As Integer = 1, z2 As Integer = 2 
      Dim s1 As String = "abc", s2 As String = "ABC" 
      Console.WriteLine("z1 = z2: {0}", z1 = z2) 
      Console.WriteLine("s1 = s2: {0}", s1 = s2) 
      Console.ReadLine() 
    End Sub 
  End Module 
End Namespace

Die Ausgabe zeigt, dass durch den Schalter Option Compare Text beim Textvergleich Groß- und Kleinschreibung gleichwertig sind.

z1 = z2: False 
s1 = s2: True

Alle Datentypen, die den Operator = nicht verwenden dürfen, verwenden die Methode Equals (der Klasse Object) zum Vergleich. Das folgende Codefragment testet zwei Objekte auf Gleichwertigkeit:


'...\Klassendesign\Autofahrer\Autofahrer.vb

Option Explicit On 
Namespace Klassendesign 
  Module Autofahrer 
    ... 
    Sub Gleich() 
      Dim Ente As Auto = New Auto() 
      Dim ZweiCV As Auto = New Auto() 
      Ente.Besitzer = "Kurt Knöffel" 
      ZweiCV.Besitzer = "Kurt Knöffel" 
      Console.WriteLine("Gleiche Autos " & _ 
        Ente.Equals(ZweiCV)) 
      Console.WriteLine("Gleiche Besitzer: " & _ 
        Ente.Besitzer.Equals(ZweiCV.Besitzer)) 
      Console.ReadLine() 
    End Sub 
  End Module 
End Namespace

Die Ausgabe ist nicht ganz wie erwartet:

Gleiche Autos False 
Gleiche Besitzer: True

Die Autos haben keine eigene Definition für Equals und verwenden diejenige von Object. Sie aber hat keine Kenntnis von Auto und kann daher sinnvoll nur auf Identität prüfen. Da es sich um zwei unabhängige Auto-Objekte handelt, ergibt der Vergleich False. Anders sieht es beim Besitzervergleich aus. Die Klasse String hat eine eigene Implementierung der Methode Equals, die den Inhalt (die Zeichenkettenfolge) vergleicht.


Hinweis
Wenn Equals Objekte inhaltlich vergleichen soll, muss die zugrunde liegende Klasse die Methode Equals neu definieren (siehe Abschnitt 3.14.5, »Equals«) oder den Gleichheitsoperator = überladen (siehe Abschnitt 3.11.3, »Vergleich«).


String

Der Datentyp String nimmt aus zwei Gründen eine Sonderstellung ein:

  • String ist sowohl ein primitiver Datentyp als auch ein Referenztyp.
  • Strings sind unveränderbar.

Der erste Punkt sorgt dafür, dass ein Vergleich mit allen drei Möglichkeiten stattfinden kann: Is, = und Equals. Der zweite Punkt erlaubt eine ressourcenschonende Speicherung von String-Literalen. Sie werden nur einmal im Speicher abgelegt, und bei jedem Auftreten eines Literals wird eine Referenz darauf verwendet. Dies kann suggerieren, dass String kein Referenztyp ist. Das folgende Codefragment weist einmal zwei Variablen das gleiche Literal zu und danach eine zusammengesetzte Zeichenkette gleichen Inhalts.


'...\Klassendesign\Autofahrer\Autofahrer.vb

Option Explicit On 
Namespace Klassendesign 
  Module Autofahrer 
    ... 
    Sub StringVergleich() 
      Dim s1, s2 As String 
      s1 = "ab" : s2 = "ab" 
      Console.WriteLine("{{s1,s2}}: {{{0},{1}}}", s1, s2) 
      Console.WriteLine("Is,=: {0},{1}", s1 Is s2, s1 = s2) 
      Console.WriteLine() 
      s1 = "a" : s2 = "b" 
      s1 = s1 & "b" : s2 = "a" & s2 
      Console.WriteLine("{{s1,s2}}: {{{0},{1}}}", s1, s2) 
      Console.WriteLine("Is,=: {0},{1}", s1 Is s2, s1 = s2) 
      Console.ReadLine() 
    End Sub 
  End Module 
End Namespace

Die erste Ausgabe zeigt, dass beim Verwenden identischer String-Literale nicht nur der Inhalt der Variablen gleich ist, sondern beide auf dasselbe Objekt zeigen (Vergleich mit Is ergibt True). In der zweiten Ausgabe sehen Sie, dass durch das Zusammensetzen von Zeichenketten trotz gleichen Inhalts verschiedene Objekte entstehen können.

{s1,s2}: {ab,ab} 
Is,=: True,True

{s1,s2}: {ab,ab} 
Is,=: False,True

Hinweis
Nur String-Literale werden nur einmalig gespeichert (und in einem Pool verwaltet), nicht aber Zeichenketten im Allgemeinen.



Rheinwerk Computing - Zum Seitenanfang

3.1.10 Sichtbarkeit der Klasse Zur nächsten ÜberschriftZur vorigen Überschrift

Bisher haben wir, der Einfachheit halber, alle Definitionen immer möglichst öffentlich gehalten. Dies ist aber kein guter Stil, da es das Prinzip der Kapselung verletzt (siehe Abschnitt 3.1.1, »Einführung«). Wenn eine Klasse Teil einer anderen ist, kann sie dieselben Sichtbarkeitsmodifikatoren haben wie jedes andere Klassenmitglied (siehe Abschnitt 3.2, »Kapselung«). Als alleinstehende Klasse kann sie überall (Public) oder innerhalb der Anwendung (Friend) sichtbar sein (siehe Tabelle 3.1). Eine fehlende Angabe ist gleichbedeutend mit Friend. Diese Bemerkungen gelten auch für andere Datentypen als Klassen.


Tabelle 3.1 Sichtbarkeitsmodifikatoren einer Klasse

Modifikator Beschreibung

Public

Eine öffentliche Klasse kann aus jeder beliebigen Anwendung heraus instanziiert werden.

Friend

Solche Klassen sind nur innerhalb derselben Anwendung instanziierbar.


Eine feinere Steuerung der Sichtbarkeit der Klasse selbst ist nicht möglich, sondern muss über die Beschränkung der Klassenmitglieder erfolgen. Verändern wir in der Datei Auto.vb, wie im nächsten Code gezeigt, den Modifikator auf Friend, bekommen wir etliche Fehlermeldungen des Compilers über unerlaubte Zugriffe von Autofahrer.vb, da Friend außerhalb der Anwendung nicht sichtbar ist und sich beide Dateien in verschiedenen Projekten befinden und damit verschiedene Anwendungen darstellen.


'...\Klassendesign\Auto\Auto.vb

Option Explicit On 
Namespace Klassendesign

  Friend Class Auto 
    Public Besitzer As String 
  End Class 
  ... 
End Namespace

Hinweis
Alleinstehende Klassen dürfen nicht mit Private oder Protected gekennzeichnet werden und sind ohne Kennzeichnung anwendungsweit benutzbar (Friend).



Rheinwerk Computing - Zum Seitenanfang

3.1.11 Aufteilung der Definition mit Partial Zur nächsten ÜberschriftZur vorigen Überschrift

Nur kleine Geister halten Ordnung, das Genie überblickt das Chaos.

Ich weiß nicht, wie Ihnen es geht, aber beim Programmieren bin ich anscheinend ein kleiner Geist, denn Ordnung in meinen Quelltexten hilft mir enorm bei der Arbeit. Je kleiner die Quelltextdateien sind, desto leichter fällt es, den Überblick zu behalten. Visual Basic unterstützt den Programmierer mit der Möglichkeit, die Definition einer Klasse auf mehrere Teile aufzuteilen, die sich in verschiedenen Dateien derselben Anwendung befinden dürfen (nicht müssen). Der Compiler setzt die einzelnen Teile automatisch zusammen, bevor der Quelltext übersetzt wird. Mindestens ein Teil muss mit dem Schlüsselwort Partial gekennzeichnet werden.


Hinweis
Die Klassenmodifikatoren der Definitionsteile werden kombiniert und müssen konsistent sein. Die Reihenfolge der Definitionsteile einer Klasse ist undefiniert.


Das folgende Codefragment setzt die Auto-Klasse aus zwei Teilen zusammen. Es zeigt, dass auch leere Teile erlaubt sind. Die Teile dürften auch in verschiedenen Dateien derselben Anwendung stehen.


'...\Klassendesign\Auto\Auto.vb

Option Explicit On 
Namespace Klassendesign

  Partial Public Class Auto 
    Public Besitzer As String 
  End Class

  Partial Public Class Auto 
  End Class

  Partial Public Class Auto 
    Public Fahrer As String 
  End Class

End Namespace

Diese Definition ist absolut gleichwertig zu:

Option Explicit On 
Namespace Klassendesign

  Public Class Auto 
    Public Besitzer As String 
    Public Fahrer As String 
  End Class

End Namespace

Hinweis
Alle Teile einer Klassendefinition mit mehreren Teilen sollten mit Partial sowie mit den gewünschten Modifikatoren (Sichtbarkeit und Vererbung) gekennzeichnet werden, um die Übersichtlichkeit zu verbessern.


Die Entwicklungsumgebung zur Erstellung grafischer Benutzeroberflächen macht rege Gebrauch von der Möglichkeit, Klassendefinitionen aufzuteilen.


Rheinwerk Computing - Zum Seitenanfang

3.1.12 Grafikbibliothek: Beispiel für Kapitel 3 und 4 topZur vorigen Überschrift

Um nicht jedes Mal wieder von vorn anfangen zu müssen, wird uns in diesem und dem nächsten Kapitel eine kleine Bibliothek begleiten, die wir im Laufe des Textes langsam erstellen. Es geht um grafische Objekte. Da wir vorerst nur Konsolenanwendungen erstellen, werden diese natürlich nicht sauber auf den Bildschirm gezeichnet. Durch das Konzept partieller Klassen kann der Quelltext einer Datei klein gehalten werden. Wir starten mit einer Miniaturklasse in einer Klassenbibliothek (vergleiche Abschnitt 3.1.5, »Projekttyp Klassenbibliothek«). Achten Sie bitte darauf, in den Projekteigenschaften den Wurzelnamensraum zu löschen. Den Inhalt der Datei ändern Sie bitte wie folgt ab (Public wird in Abschnitt 3.2, »Kapselung«, erklärt):


'...\Klassendesign\Graphik\Rechteck.vb

Option Explicit On 
Namespace Klassendesign

  Partial Public Class Rechteck 
  End Class

End Namespace

Um diese Bibliothek zu testen, fügen wir der Lösung noch eine kleine Anwendung (Projekt) namens Zeichner hinzu. Wie in Abschnitt 2.4.1, »Namensräume und Imports«, beschrieben, setzen wir den Einstiegspunkt. Wenn die Dateien über ein Netzwerk erreicht werden, vertrauen wir der Anwendung in den Sicherheitseinstellungen (siehe Abschnitt 2.3.2, »Start und Test«). Damit die Grafikbibliothek nutzbar ist, referenzieren wir sie noch und löschen den Wurzelnamensraum, wie in Abschnitt 3.1.5, »Projekttyp Klassenbibliothek«, beschrieben (dort steht auch, wie man gegebenenfalls mit einem Fehler bezüglich »prerequisite« umgeht). Schließlich machen wir die Anwendung über ihr Kontextmenü zum Startprojekt. Der Inhalt der Anwendungsdatei ist wie folgt (die Bedeutung von Shared ist hier nicht wichtig, siehe Abschnitt 3.4, »Bindung«; es wurde Class statt Module gewählt, um die Definitionen mit Partial erweitern zu können).


'...\Klassendesign\Zeichner\Zeichner.vb

Option Explicit On 
Namespace Klassendesign 
  Partial Class Zeichner

    Shared Sub Main() 
      Dim z As Zeichner = New Zeichner() 
      z.RechteckTest() 
      ... 
      Console.ReadLine() 
    End Sub

    Sub RechteckTest() 
      Dim kr As Rechteck = New Rechteck() 
      Console.WriteLine("Erledigt. ") 
    End Sub

  End Class 
End Namespace

In diesem und dem nächsten Kapitel werden wir die Grafikbibliothek sukzessive erweitern und Testroutinen zur Zeichner-Anwendung hinzufügen. Die erste Erweiterung erfolgt in Abschnitt 3.2.6, »Grafikbibliothek: private Größe des Rechtecks«.



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 Basic 2008
Visual Basic 2008
Jetzt Buch bestellen


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

 Buchempfehlungen
Zum Rheinwerk-Shop: Visual Basic 2012






 Visual Basic 2012


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






 Schrödinger
 programmiert C++


Zum Rheinwerk-Shop: IT-Handbuch für Fachinformatiker






 IT-Handbuch für
 Fachinformatiker


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






 Professionell
 entwickeln mit
 Visual C# 2012


Zum Rheinwerk-Shop: Windows Presentation Foundation






 Windows Presentation
 Foundation


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




Copyright © Rheinwerk Verlag GmbH 2009
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