| VB6 erlaubt die Verwendung von Kassen, wenn auch nicht alle Funktionen unterstützt werden die zT. in anderen Sprachen enthalten sind (zB Vererbung.) Hier wird das Klassenmodell in VB6 beschrieben. Einige Begriffe die man in Verbindung mit Klassen verwendet sind wichtig um die Beschreibungen zu verstehen. Um ein Überblick der verwendeten Begriffe zu erhalten sind sie hier kurz erklärt.
| Begriff | Bedeutung |
|---|
| Objekt-Orientiertes-Programmieren (OOP) | Ist der Oberbegriff für alles rund um Klassen und ihren Eigenschaften. Es bedeutet kurz gesagt das Programmstrukturen sich nicht nur um Daten und Prozeduren drehen, sondern um Objekte welche alles enthalten was sie benötigen um mit ihren Daten umgeben zu können, inklusive der Prozeduren, all dies wird in Objekten gekapselt. Und es bedeutet auch das Programme nicht mehr linear strukturiert sein müssen sondern Ereignisse dann behandelt werden wenn sie auftreten. | | Klasse | Ist der Konstruktionsplan für Objekte, man könnte sie mit einem Type vergleichen mit dem Unterschied das nicht nur Daten sondern auch Prozeduren und noch mehr enthalten sein können. Eine Kasse enthält in sich alle Prozeduren die sie benötigt um mit den eigenen Daten umgehen zu können. | | Objekt | Ist die verkörpert einer Klasse die aus dem Konstruktionsplan erstellt wurde und Speicher deklariert. Ähnlich wie von einem Type eine Variable deklariert werden kann, kann von einer Klasse ein Objekt deklariert werden. Ein Objekt kann die Struktur einer Klasse selbst abbilden, oder auf ein anderes Objekt verweisen. | | Instanz | Wird aus einer Klasse ein Objekt erzeugt, wird dies Instanzieren genannt, ein Objekt ist dann eine Instanz der Klasse. | | Referenz | Ein Objekt kann auch eine Referenz also ein Verweis (oder Stellvertreter) zu einem instanzierten Objekt sein, das bedeutet das viele Objekte als Reverenzen auf die gleiche Instanz eines Objekts verweisen können. Ändert sich der Wert in der Instanz ändert sich dieser auch für alle Reverenzen, die ja die Werte selbst nicht enthalten sondern auf diese nur verweisen. (In VB6 sind alle Objekte Referenzen, die Instanzen werden Intern automatisch organisiert.) | | Kapselung | Anders als in Modulen sind da Public deklarierte Namen nicht einfach im gesamten Projekt sichtbar, sondern nur über des Objekts erreichbar. Namen können so besser abgegrenzt werden und Namensüberschneidungen verhindert werden. Public¦Friend bewirken das ein Name nach Außen sichtbar ist, sie bleiben aber an das Objekt gebunden. | | Methoden (Method) | Sind die Prozeduren (Sub Function) die in einem Objekt dessen Eigenschaften bearbeiten. | | Eigenschaften (Property) | Ist eine Schnittstelle für den Datenaustausch in und aus dem Objekt, die es auch ermöglicht zusätzliche Aktionen beim Schreiben und Lesen von Daten Auszuführen. | | Ereignis (Event) | Objekte können Ereignisse auslösen, das bedeutet das ein im Objekt deklariertes Ereignis als Prozedur in einem anderen Codeteil ausgeführt wird als im Objekt selbst. zB beim drücken auf ein Knopf wird ein Ereignis ausgelöst das in einem Formular bearbeitet werden kann. | | Überladung | Bedeutet das für eine Prozedur mehrere Varianten erlaubt sind, die zB. unterschiedliche Anzahl und Daten-Typen von Parametern erlauben. Das ermöglicht es unteranderem das eine Funktion für viele Daten-Typen gleichnamig verwendet werden kann. (Die Funktion Len() ist ein Beispiel, man kann Len() auf alle Datentypen anwenden, obwohl für jeden Daten-Type eine eigene Prozedur ausgeführt wird.) Leider unterstützt VB6 das Überladen von Prozeduren nicht. | | Polymorphie | Dieser eigentlich unnötig komplizierte aber in OOP häufig benutze Begriff bedeuten soviel wie Vielgestaltigkeit, das heißt das ein Algorithmus nicht an eine bestimmten Daten-Typ gebunden ist. Mehrere Klassen können die selben Eigenschaften oder Methoden bereitstellen und beim Aufruf der Eigenschaft¦Methode muß nicht bekannt zu sein zu welcher Klasse das betreffende Objekt gehört. Dies erleichtert das Programmierer da es so möglich ist Algorithmen nur einmal zu entwickeln und sie dann vielfältig in anderen Objekten benutzen zu können. (Überladung von Prozeduren, oder der Variant und Object Daten-Typ sind auch eine Form der Polymorphie. Leider unterstützt auch hier VB6 Polymorphie nicht vollständig (nicht über Vererbung, nur über Schnittstelle), zB. gibt es in VB6 eine Reihe unterschiedlicher Listen-Formate, es gibt aber keine Möglichkeit sie untereinander austauschbar zu verwenden. Aber es werden dennoch einige polymorphe Eigenschaften unterstützt. | | Vererbung | Bedeutet das eine Klasse Codes an andere Klassen vererben¦übertragen¦kopieren kann. so lassen sich Codes mit gleichen aufgaben in vielen Klassen verwenden ohne sie neu schreiben zu müssen. Vererbung kann auch mit der Polymorphie zusammenarbeitet und ermöglicht es so das nicht in jenem Klasse wiederholende Prozeduren immer wieder neu geschrieben werden müssen. Durch die Kapselung wäre sonst kein Austausch von Codes unter Klassen möglich, sie wären in den Klassen einsperren. Leider unterstützt VB6 Vererbung nicht, statteten wird eine Schnittstellen Kommunikation unterstützt welche aber weniger effizient ist. | | Nicht-Linearität | Durch die Ereignis-Orientierte Programmierung ist ein Programm nicht mehr linear, in dem Sinne wie es Codes in einem Standard-Modul sind. Ein Beispiel sind Benutzeroberflächen, in einem Linearen Programm müsse eine Schleife und ein Select-Case prüfen ob eine Aktion ausgeführt wurde die eine Prozedur und Aktionen auslöst, zB. beim Klicken auf ein Knopf oder Menü. Durch Event fällt dies weg, die Aktion wird dann ausgeführt wenn sie eintritt. Die Struktur eines Programms läßt sich deshalb nicht mehr linear abbilden, die Ereignisse verändern die Daten in einem Objekt wenn sie eintreten und theoretisch könne sie das auch gleichzeitig. | | Task, Multitasking | Prozeß oder Programm der in einer Multitasking Umgebung gleichzeitig mit anderen Tasks ausgeführt werden kann. Heutige Betriebsysteme verwenden alle Multithreading um mehrere Programme und Prozesse gleichzeitig laufen lassen zu können. | | Thread, Multithreading | Ein Thread ist ein Programmteil (innerhalb eines Task) welcher von einem anderen unabhängig arbeiten kann. So ist es möglich das auch innerhalb eines Programms verschiedene Aufgaben gleichzeitig bearbeiten werden können. Besonders interessant in Multi-Prozessor Systemen, aber auch in Single-Prozessor Systemen kann es Beschleunigung bringen wenn unterschiedlich Hardware aufgaben gleichzeitig stattfinden können. Es kann Probleme geben wenn Threads gleichzeitig die selben Daten benutzen¦verändern deshalb müssen Thread voneinander abgegrenzt (das sich keine Daten überschneiden), oder synchronisiert (Treads nacheinander bearbeiten) werden. Da zusätzlich Management Aufgaben anfallen die den Code auch verlangsamen können muß sich der Entwickler überlegen für welche Codes Treads sinnvoll sind. (VB6 erlaubt leider kein Multithreading) |
Da in Objekten oft gleiche Aufgaben erfüllt und gleiche Daten bearbeitet werden müssen, ist es sinnvoll dies auch in alle Projekten gleich zu benennen. Auf diese Weise ist es viel leichter sich in Projekten zurecht zu finden, und da Objekte die Namen kapseln gibt es auch keine Probleme mit Namensüberschneidungen. Das "_" Unterstrich-Zeichen kann zwar in Namen verwendet werden, könnte aber Konflikte mit Ereignisse auslösen, die den Unterstrich benutzen. (Siehe: Ereignis: Event) Ansonsten gelten die gleichen Regeln wie auch bei der Benennung von Klassen Namen. (Siehe: Namensvergabe)
Hier eine Liste der gebräuchlichsten Namen in Klassen.
| Wort | Bedeutung |
|---|
| | | Methoden | |
|---|
| Add, AddItem | Fügt ein Element hinzu | | Move, MoveItem | Verschiebt ein Element an eine andere Position | | Remove, RemoveItem | Löscht ein Element | | Clear | Löscht den gesamten Inhalt | | | | Eigenschaften | |
|---|
| List | Der Inhalt der Liste | | Item | Ein Element (aus einer Liste) | | Index | Den Index auf eine Position in einer Liste | | Count | Anzahl Elemente | | Name | Name des Objekts¦Elemente | | Caption | Titel, Sichtbarer Text des Objekts | | Text | Text-Inhalt im Objekt | | | | Ereignisse | |
|---|
| Initialize() | Tritt auf, wenn eine Instanz (Objekt) einer Klasse erstellt wird. | | Terminate() | Tritt auf, wenn eine Instanz (Objekt) aus dem Speicher entfernt worden sind. (oder alle (Objekt-Verweise auf eine Instanz) | | | | Load() | Tritt auf, wenn ein Objekt (Formular oder Steuerelement) geladen wird. | | Unload(Cancel As Integer) | Tritt auf, unmittelbar bevor wenn ein Objekt (Formular oder Steuerelement) entfernt wird. | | Activate() | Tritt auf, wenn ein Objekt (Formular oder Steuerelement) zum aktiven wird. | | Deactivate() | Tritt auf, wenn ein Objekt (Formular oder Steuerelement) nicht mehr das aktive Fenster ist. |
Klassen-Module enthaten sozusagen ein Konstruktionsplan eines Objekts. Sie Enthalten alles was das Objekt braucht, also sowohl seine Dateien wie auch die Prozeduren (Methoden) um diese zu verwalten. Von einer Klasse können beliebig viele Objekte erzeugt¦abgeleitet werden, Objekte sind sozusagen "Verkörperungen" einer Klasse. Die Namen die Public sichtbar sind gehören zu der sogenannten Schnittstelle eines Objekts. In VB6 ist es leider nicht möglich in einem Klassen- Modul mehrere Klassen unterzubringen. Ein Klassen- Modul gilt automatisch als eine Klasse.
| Name | Schlüsselworte | Beschreibung |
|---|
| Eigenschaften | Property (Get Let Set) | Sind die Daten die im Objekt gespeichert werden, welche über Eigenschaftsprozeduren ausgetauscht und bearbeitet werden können. | | Methoden | Sub Function | Sind die Prozeduren die im Objekt verfügbar sind. | | Ereignisse | Event RaiseEvent WithEvents | Sind Aktionen die vom Objekt ausgelöst werden können und in anderen Objekten außerhalb der Ereignisquelle eine Prozedur aufrufen. |
| Klassen-Modul | Standard-Modul |
|---|
| Von Klassen lassen sich unbegrenzt viele Objekte und damit auch deren Werte erzeugen. | In Modulen sind alle Werte nur einmal verfügbar. | | Dadurch das Objekte instanziert werden müssen und auch wieder gelöscht werden können, existieren Prozeduren und Variablen nicht während der Ganzen Laufzeit. Ein Objekt kann auch Nothing oder Null enthalten. | Prozeduren und Variablen existieren in Modulen während der gesamten Laufzeit. | | Public Namen ist in Objekt gekabbelt und können nur über dieses erreicht werden. | Public Namen sind im ganzen Projekt direkt sichtbar und können in allen Prozeduren verwendet werden. | | In Klassen können Ereignisse ausgelöst werden, welche Prozeduren aufrufen. | In Modulen existieren Ereignisse nicht. | | Klassen können bei der "Erzeugen" und "Zerstören" Initialisierungen und Terminationen ausführen. | Initialisierungen und Terminationen existiert in Standard-Modulen nicht. |
Einige Namen dürfen nicht verwendet werden da sie zu den zugrundeliegenden Schnittstellen "Unknown" und "Dispatch" gehören: QueryInterface, AddRef, Release, GetTypeInfoCount, GetTypeInfo, GetIDsOfNames, Invoke Public hat nicht die gleiche Wirkung wie Public in Modulen, Namen sind nicht im ganzen Projekt sichtbar, sondern durch die Kapselung nur über das Objekt erreichbar und nach Außen sichtbar. Es ist leider nicht möglich Public sichtbare Namen in einer Klasse wie in einem Modul zu deklarieren. Global sichtbare Namen müssen außerhalb von Klassen in einem Modul deklariert werden. Konstanzern können leider überhaupt nicht Public dekoriert werden. (Das liegt daran das VB6 nicht unterschiedet ob eine Klasse nur innerhalb eines Projekts sichtbar sein muß, oder über dies hinaus wie zB. in eine DLL OCX. In extern sichtbaren Namen die nur zur Laufzeit aufgelöst werden können, gibt es keine Konstanten da Werte immer abgeholt und in einer Variable übertragen werden müssen.)
| Schlüsselwort | Beschreibung |
|---|
| Public | Namen sind über das Objekt nach außen sichtbar für alle, auch außerhalb des Projekts. (In OCX DLL ActiveX usw. können Namen zugänglich sein.) | | Friend | Namen sind über das Objekt nach außen sichtbar für alle Prozeduren in einem Projekt, nicht aber außerhalb des Projekts.). | | Private | Namen sind nur innerhalb des Objekt unter den Prozeduren sichtbar (wie in Modulen auch.) |
In Gegensatz zu Modulen kommt noch das Schlüsselwort Friend hinzu, für Friend gelten zusätzliche Einschränkungen Kann nur in Formular-Modulen und Klassen-Modulen verwendet werden. Kann nur Prozedurnamen, nicht Variablen oder Typen verwendet werden. Eine Friend- Prozedur kann nur zur Compilierungszeit (nicht zur Laufzeit) auflösbar sein. (Friend-Prozeduren sind dadurch schneller aufrufbar.) Nicht sichtbar für den Controller einer Instanz des Objekts und dadurch außerhalb des Projekts nicht sichtbar und gehören deshalb nicht zur der Schnittstelle. (in eine DLL OCX Datei sind Friend-Prozeduren nach Außen nicht erreichbar.) Sie sind deshalb auch nicht sichtbar in Objekten die als allgemeine "As Object" deklariert wurden, da diese polymorph und nur zur Laufzeit auflösbar sind. Um auf Friend deklarierte Namen zugreifen zu können müssen Objekte explizit mit Klassennamen deklariert werden um zur Compilierungszeit auflösbar zu sein.
Nützlich ist Friend auch in ActiveX Komponenten, weil so Prozeduren innerhalb der Komponenten sichtbar sein können aber nicht außerhalb, was sie besser kapseln kann als ein Public wenn sie nach Außen auch nicht erreichbar sein sollen.
Me gilt als Stellvertreter oder Verweis auf sich selbst, in das Objekt in dem sich das Me befindet. Es ist also sinnvoll immer dann wenn man eine interne Eigenschaft des Objekts ansprechen will dies nicht über den Namen zu tun sondern über das Schlüsselwort "Me". (zB. nicht "Form1.Unload" sondern "Me.Unload")
Es können auch in einer Klasse Public Variabeln deklariert werden, aber mit Propertys (Eigenschaft) ist es möglich eine Schnittstelle für den Datenaustausch in und aus dem Objekt zu schaffen und so beim lesen und schrieben auf ein Property auch Codes auszuführen, (wie zB. eine Bereichsprüfung). Deshalb werden sie auch Eigenschaftsprozeduren genannt. Sowohl für den Schreib- wie für den Lese-Vorgang wird separat in einer Eigenschaftsprozeduren Deklariert. Wird die Schreib-Property (Let Set) weggelassen, gilt die Eigenschaft als Schreibgeschützt und kann außerhalb des Objektes nicht (direkt) geändert werden. So können anders als bei Variablen Werte nach Außen vor Veränderung geschützt werden. (zB. wird die Anzahl in einer Liste nicht durch Count bestimmt sondern nur zurückgegeben, durch eingefügten und gelöschten von Elementen wird Count Intern geändert.) Public deklarierte Variabeln werden von VB6 intern als Property behandelt. (Die Verarbeitung ist also auch nicht schneller.) Der Unterschied zwischen Methoden (Prozeduren) und Property (Eigenschaftsprozeduren) ist manchmal garnicht so leicht da ja beide eine Prozedur ausführen. Am Ende zählt ob es sich eher um eine Funktion oder um Werte handelt, und dementsprechend sollte die Wahl zwischen den beiden Möglichkeiten getroffen werden.
| Ereignisprozedur | Auslöser | Beschreibung |
|---|
| Property Get | Var1 = Prob1 | Gibt den Wert einer Eigenschaft zurück. | | | | | Property Let | Prob1 = Var1 | Legt den Wert einer Eigenschaft fest. | | Property Set | Set Prob1 = Obj1 | Legt den Wert einer Objekteigenschaft fest (d.h. einer Eigenschaft, die eine Referenz auf ein Objekt enthält). |
'======== Class1 (Eine Klasse die Property enthält)
'-------- Deklaration
'-- Interne Propertys speichern
Private Type PropertysInternType
Prop1 As Long ' Variable Deklarieren
Prop2 As Class2 ' Objekt mit expliziter Klasse deklarieren (nur Objekte dieser Klasse sind übertragbar)
End Type
Private PropertysIntern As PropertysInternType
'-------- Code
'-- Variabeln-Property (Eigenschaftsprozeduren)
Public Property Get Prop1() As Long
'{... Code}
Prop1 = PropertysIntern.Prop1 ' der Wert wird zurückgegeben
End Property
Public Property Let Prop1(ByVal PropertyVal1 As Long)
'{... Code}
PropertysIntern.Prop1 = PropertyVal1 ' der Wert wird übernommen
End Property
'-- Variabeln-Property (Eigenschaftsprozeduren)
Public Property Get Prop2() As Class2
'{... Code}
Set Prop2 = PropertysIntern.Prop2 ' der Wert wird zurückgegeben
End Property
Public Property Set Prop2(ByVal PropertyVal1 As Class2)
'{... Code}
Set PropertysIntern.Prop2 = PropertyVal1 ' der Wert wird übernommen
End Property
'======== Externes Modul
Public Sub Main()
Dim ObjP As New Class1 ' Instanz erstellen zum Prüfen der Property in "Class1"
Dim Var1 As Long ' Temporäre Variablen
Dim Obj1 As New Class2
ObjP.Prop1 = Var1 ' Ausführung: "Property Let Prop1", "Var1" wird ins Objekt geschrieben
Var1 = ObjP.Prop1 ' Ausführung: "Property Get Prop1", der Wert wird zurückgegeben.
Set ObjP.Prop2 = Obj1 ' Ausführung: "Property Set Prop2", "Obj1" wird ins Objekt geschrieben
Set Obj1 = ObjP.Prop2 ' Ausführung: "Property Get Prop2", das Objekt wird zurückgegeben.
Debug.Print ObjP.Prop1 ' Ausführung: "Property Get Prop1", und nur während der Entwicklungszeit !
End SubWird ein Variant verwendet kann es auch sein das alle drei Eigenschaften gleichzeitig verwendet werden müssen um alle Möglichkeiten zu behandeln.
'-------- Deklaration
Private Type PropertysInternType
Prop1 As Variant ' Variable Deklarieren
End Type
Private PropertysIntern As PropertysInternType
'-------- Code im Objekt
Public Property Get Prop1() As Variant
If IsObject(PropertysIntern.Prop1) Then
' Ist ein Objekt
Set Prop1 = PropertysIntern.Prop1
Else
' Ist kein Objekt
Prop1 = PropertysIntern.Prop1
End If
End Property
Public Property Set Prop1(ByVal Par1 As Variant)
' Ist ein Objekt
Set PropertysIntern.Prop1 = Par1
End Property
Public Property Let Prop1(ByVal Par1 As Variant)
' Ist kein Objekt
PropertysIntern.Prop1 = Par1
End Property
'-------- Code außerhalb vom Objekt
Set Obj2 = Obj1.Prop1 ' Objekt Aufruf Get
Var2 = Obj1.Prop1 ' Variable Aufruf Get
Set Obj1.Prop1 = Obj2 ' Objekt Aufruf Set
Obj1.Prop1 = Var2 ' Variable Aufruf LetDie Lesende Eigenschaftsprozedur "Get" benötigt keinen Parameter, die Schreibenden "Let" "Set" mindestens einen welcher den Wert übernimmt der zugewiesen wurde. Die Eigenschaftsprozeduren müssen deckungsgleich sein, das heißt die Namen müssen gleich lauten und die Parameterangaben ebenfalls. Werden mehrere Parameter verwendet ist der letzte Parameter der Übergabewert, die vorangehenden die zusätzlichen Parameter. Der Datentyp des letzten Arguments in einer "Property Set"-Deklaration muß entweder ein Objekt-Typ oder der Daten-Typ Variant sein.
'-- Pseudocode
' D ist die Übergabe Variable (Objekt-Typ oder Variant)
Prop1 = D ' Diese Anweisung löst...
Public Property Let Prop1(D) ' ... Diese Eigenschaftsprozedur aus
D = Prop1 ' Diese Anweisung löst...
Public Property Get Prop1() As {Daten-Typ von D} ' ... Diese Eigenschaftsprozedur aus
Set D = Prop1 ' Diese Anweisung löst...
Public Property Set Prop1() As {Daten-Typ von D} ' ... Diese Eigenschaftsprozedur aus
Prop1(A, B, C) = D ' Diese Anweisung löst...
Public Property Let Prop1(A, B, C, D) ' ... Diese Eigenschaftsprozedur aus
D = Prop1(A, B, C) ' Diese Anweisung löst...
Public Property Get Prop1(A, B, C) As {Daten-Typ von D} ' ... Diese Eigenschaftsprozedur ausFür außerhalb des Projekts sichtbare Schnittstellen müssen diese über PropertyBag Organisiert werden, um einerseits die Namen sichtbar zu machen und anderseits die Daten zu initialisieren und zwischen zu speichern. Ein gutes Beispiel dafür sind Benuzerdefinierte-Steuerelemente. Was man im Eigenschaftsfenster sehen und einstellen kann wird über das PropertyBag zur Verfügung gestellt.

Methoden sind Objekt-Prozeduren (Sub, Function) innerhalb einer Klasse, sie können genauso deklariert werden wie in einem Standard- Modul. (Siehe: Prozeduren)
Ein Beispiel für Ereignisse sind auch in den Formularen zu finden, die Ereignisse automatisch erzeugen wenn ein Formularelement erzeugt wird. Die "WithEvents" und "Set-New" Deklaration wird dabei automatisch im Hinderung erzeugt und die WithEvents-Objekte nach den Elemente-Namen benannt. Wird also ein Knopf erzeugt mit dem Namen "Command1" wird ein "Command1" WithEvents-Objekte aus der Klasse "CommandButton" erzeugt und instanziert. zB. "Command1_Click" ist dann ein Ereignis das beim klicken auf den Knopf ausgelöst wird, wobei "Click" eines der Ereignisse aus der CommandButton- Klasse ist. Ein anderes Beispiel für ein Ereignis wäre eine Rückmeldung für eine Fortschrittsanzeige in einer Methode die viel Zeit in Anspruch nimmt bevor sie beendet ist. Das ist auch deshalb nützlich weil eben Objekte all ihre Prozeduren in sich enthalten sollten, also auch die Verwaltung einer Fortschritts-Berechnung. So kann das aufgerufene Objekt über ein Ereignis dem aufrufenden Objekt mitteilen, wo es sich in der Berechnung befindet und diese Information kann auswerten und zB. anzeigen wenn das aufrufende Objekt ein Formular ist.

'-------- Deklaration
Public Event Evt1() ' Ein Event wurde deklariert
Public Event Evt2(ByVal Par1 As Single, ByRef Cancel As Boolean) ' "Cancel" kann hier als Abbruchs-Variable verwendet werden. Die über Event deklarierten Ereignisse können nun in der Klasse ausgelöst werden. Die funktioniert eigentlich wie bei einem Call nur diesmal über das Schlüsselwort RaiseEvent.
'-------- Code
RaiseEvent Evt1 ' das Deklarierte Ereignis wird ausgeführt
RaiseEvent Evt2(Par1, Cancel) ' hier werden Parameter übergeben, und über Cancel kann ein Rückgabewert verwendet werden um lange Prozesse abzubrechen.Ist die externe Deklaration weil sie Ereignisse eines anderen Objekts im eigenen zugänglich macht und hier das Ereignis ausgeführt wird das von der Ereignisquelle ausgelöst wurde.
WithEvents deklariert Ereignisse aus einem Objekt um diese abfangen zu können. Bei der Deklaration ist folgendes zu beachten. Kann in nicht in Standard-Modulen verwendet werden, nur in Klassen-Modulen (also auch in Formularen). WithEvents muß explizit mit Klassenname deklariert werden, polymorph "As Object" "As Variant" geht nicht. WithEvents-Variablen können keine Arrays sein. Wird WithEvents für ein Objekt aus einer Klasse deklariert die keine Ereignisquelle ist, also keine Event Deklarationen enthält, tritt ein Fehler auf.
Die Ereignisse werden nur dann ausgelöst, wenn auch eine Instanz der WithEvents Objekt-Variable erzeugt wurde, wird diese Objektvariable auf Nothing gesetzt, werden auch de Ereignisse nicht mehr ausgelöst.
'-------- Deklaration
Private WithEvents EvtClass1 As Class1 ' Es wird deklariert das Ereignisse aus der Klasse "Class1" ausgelöst werden können. Dies ist aber noch kein instanziertes Objekt, sondern nur eine Deklaration, Ereignisse werden noch nicht ausgeführt Ist eine WithEvents-Variable deklariert und Instanziert, werden ausgelöste Ereignisse an die Ereignisprozeduren geleitet. Die Ereignisprozeduren werden wie folgt deklariert WithEventsVariabelName_EreignisName(DeklarierteParameter). Die DeklarierteParameter werden so angegeben wie in Events deklariert.
'-------- Code
Private Sub Form_Initialize() ' die Ereignis-Variable wird hier mein Initialisieren eines Formulars instanziert.
Set EvtClass1 = New Class1 ' hier wird aus dem deklarierten Ereignis-Objekt eine Instanz erzeugt, erst jetzt werden Ereignisse auch ausgeführt.
End Sub
Set EvtClass1 = Nothing ' Steht irgendwo im Code eine Löschung der Ereignis-Objekt Instanz, werden keine Ereignisse mehr ausgeführt.
Private Sub EvtClass1_Evt1()
'{...Code für das ausgelösten Ereignis}
End Sub
Private Sub EvtClass1_Evt2(ByVal Par1 As Single, ByRef Cancel As Boolean)
'{...Code für das ausgelösten Ereignis}
Cancel = True ' in diesem Beispiel ist es möglich zeitaufwendige Prozesse durch "Cancel" abzubrechen.
End SubDieses Beispiel enthält 2 Klassen, eine als Auslöser und eine als Ausführer von Ereignissen. '======== "Class1": Klasse der Ereignis-Quelle
'-------- Deklaration
'-- Ereignisse deklarieren
Public Event Evt1() ' Ein Event wurde deklariert
Public Event Evt2(ByVal Par1 As Single, ByRef Cancel As Boolean) ' Cancel kann hier als Abbruchs-Variable verwendet werden
'-------- Code
'-- Ist eine Test-Prozedur die Ereignisse auslöst
Public Sub TestEvt1(ByVal Par1 As Long)
Dim Cancel As Boolean
'{... Code mit Schleifen-Wiederholung und langer Laufzeit}
RaiseEvent Evt1 ' Ereignisse werden ausgelöst
RaiseEvent Evt2(Par1, Cancel)
If Cancel Then Exit Sub ' Bricht die Prozedur ab
'{... Code mit Schleifen-Wiederholung und langer Laufzeit}
End Sub
'======== "Class2": Klasse der Ereignis-Verarbeitung
'-------- Deklaration
Private WithEvents EvtClass1 As Class1 ' Es wird deklariert das in dieser Klasse Ereignisse aus einer anderen Klasse "Class1" ausgelöst werden können. Dies ist aber noch kein Instanziertes Objekt, sondern nur eine Deklaration, es werden noch keine Ereignisse ausgelöst.
'-------- Code
'-- Aktivieren der Ereignisausführung bei der Initialisierung
Private Sub Class2_Initialize()
'Dim EvtClass1 As New Class1 ' Diese Deklaration einer WithEvents-Variable ist nicht zugelassen.
Set EvtClass1 = New Class1 ' hier wird aus dem Deklarierten WithEvents-Objekt eine Instanz erzeugt. Erst jetzt werden Ereignisse ausgeführt.
End Sub
'-- Ereignisausführung
Private Sub EvtClass1_Evt1()
Debug.Print "EvtClass1_Evt1"
'{...Code }
End Sub
Private Sub EvtClass1_Evt2(ByVal Par1 As Single, ByRef Cancel As Boolean)
Debug.Print "EvtClass1_Evt2" ' Wert aus der Ereignisquelle können über die Parameter verwandet werden.
'{...Code }
Cancel = True ' in diesem Beispiel ist es möglich zeitaufwendige Prozesse über "Cancel" abzubrechen.
End SubNun können von einer Klasse Objekte erzeugt werden.
Wichtig ist nun das unterscheiden werden muß wischen deklarierten und instanziert¦referenziert Objekt-Variabeln. Während ein Standard Daten-Typ bereitsteht in dem Moment wo durch die Dim Deklaration Speicher zugewiesen wurde, kann ein Objekt nach einer Dim Deklaration zwar den Speicher reservieren, dennoch aber noch auf Nichts -> Nothing verweisen. Dabei werden 2 Arten der Deklaration unterschieden, die Instanz einer Klasse und die Referenz zu einem Objekt. Für die Benutzung spielt dies keine so große Rolle, aber für die Geschwindigkeit. Die Instanz ist sie Verkörperung einer Klasse zu einem Objekt. Sie enthält die tatsächlichen Daten des Objekts. Die Referenz hingegen ist ein Verweis auf ein bereits bestehendes Objekt, sie enthält selbst die Daten nicht, sondern verweist intern über ein Zeiger auf das Tatsächliche Instanzierte Objekt welches die Daten enthält. Deshalb sind Referenzen auch langsamer als Instanzen da die Daten auf die sie verweisen erst geholt werden müssen bevor sie verwendet werden können. Dabei übernimmt VB6 vieles auch automatisch, was in der Praxis manchmal auch vermissend und sogar zu problematisch sein kann. VB6 erzeugt Instanzen auf die zugegriffen wird automatisch, und zerstört¦löscht diese auch automatisch wenn keine verweise mehr auf die Instanz existieren. Es ist also auch Aufgabe des Programmierers die Codes so zu schreiben das er den Überblick über die Existenz von Objekten behalten kann. Am Ende des Programms sollten alle Objekte auf Nothing gesetzt werden. Auch da beim beenden des Programms alle Objekte gelöscht sein sollten. (Ein Beispiel ist hier das beenden eines Programms mit End. Da das Programm so abrupt unterbrochen wird, verbleiben Objekte also auch Formulare im Speicher).
Wird die Instanz erzeugt, tritt ein Initialize() Ereignis auf. Wird die Instanz gelöscht¦zerstört tritt ein Terminate() Ereignis auf. Auch auf Objektnamen kann With angewendet werden. Objekte können auch in Arrays deklariert werden. Es können zwei polymorphe Daten-Typen verwendet werden statt einer expliziten Deklaration mit einem Klassennamen. Polymorphe Typen können nur während der Laufzeit (langsam) und nicht schon während der Compilierungszeit (schneller) aufgelöst werden. Zur Compilierungszeit auflösbare Variablen können über DispID oder virtual-table¦vtable aufgelöst werden. (Da VB6 keine Vererbung unterstützt ist dies die schnellste Variante.) Object kann alle arten von Objekten aufnehmen, unabhängig von deren Klasse. Variant kann sowohl Objekte wie auch Standard Daten-Typen aufnehmen.
| Code ......................... | Beschreibung |
|---|
| Dim ObjName As New ClassName | Deklariert die Objekt-Variabe und bereitet eine Instanz vor, erzeugt sie aber noch nicht und "Class_Initialize()" Ereignis wird noch nicht ausgelöst. Die Instanz wird erst dann erzeugt wenn das erste man auf da Objekt zugegriffen wird. | | Dim ObjName As ClassName | Deklariert nur die Objekt-Variabe und bestimmt welcher Klasse sie angehört, Instanziert wird nichts. Die Deklaration sichert dabei am das Objekt-Variabe immer mit dem richtigen Klassen-Typ verwendet wird. | | |
|---|
| Set ObjName = New ClassName | Deklariert die Objekt-Variabe und bestimmt welcher Klasse sie angehört, und erzeugt eine Instanz, "Class_Initialize()" Ereignis wird ausgelöst. | | Set ObjName = ObjName2 | Erzeugt ein Reverenz-Objekt und keine Instanz eines Objekts, also nur ein Verweis. Ändert sich Werte in der Instanz, ändern sich diese auch für alle Reverenz-Objekte die ja nur auf die Instanz verweisen. "Class_Initialize()" Ereignis in ObjName wird ausgelöst. | | Set ObjName = Nothing | Das Objekt wird freigegeben. Gibt es keine weiteren Referenzen mehr wird die Instanz des Objekt gelöscht¦zerstört. "Class_Terminate()" Ereignis in ObjName wird ausgelöst. | | |
|---|
| ObjName1 = ObjName2 | Fehler: Das Kopieren des Inhalts eines Objekts auf ein anderes (ähnlich wie bei einem Type) ist so leider nicht möglich. |
'---- Varianten der Objekt-Erzeugung
'-- Dim-New Deklaration
Dim Obj1 As New Class1 ' hier wird die Variable "Obj1" von der Klasse "Class1" Deklariert, und eine Instanz vorbereiten aber nicht erzeugt
Obj1.Var1 = 1 ' die Instanz wird jetzt beim ersten Zugriff auf das Objekt erzeugt, "Class_Initialize()" Ereignis wird ausgeführt
'-- Set-New Deklaration, (dies ist die bevorzugte Schreibweise, da mit "Dim" immer nur deklariert wird, und "Set" die Instanzierung vornimmt.)
Dim Obj1 As Class1 ' hier wird nur die Variable "Obj1" von der Klasse "Class1" deklariert, keine Instanz
Set Obj1 = New Class1 ' Objekt wird deklariert und die Instanz gleich erzeugt, "Class_Initialize()" Ereignis wird ausgeführt
Obj1.Var1 = 1 ' alles steht bereit
'-- Set Deklaration (Objekt-Referenzen)
Dim Obj1 As Class1
Dim Obj2 As Class1
Set Obj1 = New Class1 ' Objekt wird deklariert und die Instanz gleich erzeugt, "Class_Initialize()" Ereignis wird ausgeführt
Set Obj2 = Obj1 ' Objekt-Referenz wird erzeugt, "Obj2" verweist auf "Obj1"
Obj1.Var1 = 1 ' Änderungen sind für "Obj1" und "Obj2" sichtbar.
Debug.Print Obj2.Var1
'-- Freigeben
Set Obj1 = Nothing
'-- Fehler
Dim Obj1 As Class1 ' hier wird nur die Variable "Obj1" von der Klasse "Class1" deklariert, keine Instanz
Obj1.Var1 = 1 ' dies verursacht ein Fehler den es existiert noch keine Instanz| Typ | Anwendung |
|---|
| Object | Universaltyp, Alle Objekte | | Variant | Universaltyp, ist eigentlich kein Objekt aber kann auch Objekte aufnehmen | | Form | Alle Formulare in Anwendungen (einschließlich untergeordneter MDI-Formulare und des MDI-Formulars) | | Control | Alle Formular-Steuerelemente in Anwendungen | | MDIForm | Ein MDI-Formular in der Anwendung (wenn eines enthalten ist) |
'-- Folgende Elemente können nicht mit New erstellen werden
Dim Obj1 As New Integer ' keine Standard Daten-Typen.
Dim Obj1 As New Control ' keine allgemeiner Objekttypen.
Dim Obj1 As New ListBox ' keine spezifische Steuerelementtypen.
Dim Obj1 As New lstNames ' keine spezifischer Steuerelemente. Generische Objekt-Variablen (also mit As Object deklarierte Variablen) können Objekte unterschiedlichster Klassen enthalten. Ebenso können Variablen, die mit den integrierten Form- und Control-Typen von Visual-Basic deklariert wurden, Formulare und Steuerelemente unterschiedlicher Klassen enthalten. Da ein Objekt unterschiedliche Klassen angehören können, enthalten sie auch unterschiedliche Daten und Funktionen. Um also korrekt auf ein spezielles Objekt reagieren zu können muß man dessen Klasse feststellen können.
' Prüf ob es such um das gleiche Objekt handelt
If Obj1 Is Obj2 Then
End If
' Prüft ob es sich um ein Objekt aus der Klasse Class1 handelt
If TypeOf Obj1 Is Class1 Then
End If
' Prüft über den String-Name ob es sich um ein Objekt aus der Klasse Class1 handelt
If TypeName(Obj1) = "Class1" Then
End If


| Eigenschaft / Methode | Beschreibung |
|---|
| Add (Methode) | Fügt ein Elemente hinzu. | | Remove (Methode) | Löscht ein Element aus der Auflistung (über Index (Ganzzahl) oder Schlüssel (String-Text)). | | Item (Methode) | Gibt ein Element zurück, (über den Index oder den Schlüssel). | | Count (Eigenschaft, schreibgeschützt) | Gibt die Anzahl der Elemente in der Auflistung. |
Ein Index ist ein ganzzahliger Wert des Daten-Typs Long und reicht von Eins (1) bis zur Anzahl der Elemente der jeweiligen Auflistung. Sie können den Anfangswert des Indexes für ein bestimmtes Element mittels der benannten Argumente before und after festlegen. Der Index eines Item (Elementes) kann sich ändern, wenn neue Elemente hinzugefügt oder vorhandene gelöscht werden. Private Sub Test1(ByRef Par1 As Objekt)
Dim Var1 As Long
Dim ListIndex1 As Long
Dim ListElement1 As Variant
Set ObjList1 As New Collection ' Instanziert eine Objektliste aus der Klasse Collection
ObjList1.Add Par1 ' Objekt wird der Liste hinzugefügt
ObjList1.Add Par1, "Key1" ' Objekt wird der Liste hinzugefügt, mit dem Schlüsselwort "Key1"
ObjList1.Add Par1, "Key0", before:=2 ' Ein Objekt wird als Referenz für die Positionierung in der Liste verwendet
ObjList1.Add Par1, "Key3", after:=2 '
ObjList1.Remove 1 ' Löscht ein Element aus der Liste
ObjList1.Remove "Key3" ' Löscht ein Element aus der Liste
Var1 = ObjList1.Count ' Gibt die Anzahl an Elementen in der Liste zurück
Set ListElement1 = ObjList1.Item(1) ' Erstellt eine Referenz auf das Element 1.
Set ListElement1 = ObjList1.Item("Key1") ' Erstellt eine Referenz auf das Element mit dem Schlüsselwort "Key1"
For Each ListElement1 In ObjList1 ' Die Schleife durchläuft alle Elemente in der Liste (For-Each ist schneller)
'{... Code, Elemente der Liste bearbeiten}
Var1 = ListElement1.EinWert
Next
For ListIndex1 = 1 To ObjList1.Count ' Die Schleife durchläuft ein Bereich von Elementen in der Liste (For-Each ist schneller)
'{... Code, Elemente der Liste bearbeiten}
Var1 = ObjList1.Item(ListIndex1).EinWert
Next
End SubDie beliebteste Frage im Bereich der Programmierung ist "was ist besser", und die unbeliebte Antwort ist meistens "kommt darauf an". Es ist grundsätzlich so das man nicht immer alles auf einmal inklusive aller Vorteile und ohne Nachteile haben kann, oft sind sie gegensätzlich oder voneinander abhängig so das gerade die Vorteile auch die Nachteile hervorbringen. Aus dem Grund sind einer kurz die Vor- und Nachteile des Klassen- und Modul-Models beschrieben um ein wenig bei der Entscheidung zu helfen welchen Weg man für welche Aufgaben am besten wählen kann.
Objekt-Orientiert: das herausragende ist sicher das Objektmodell, welches es ermöglicht in ein Paket alles hinein zu bündeln was es braucht, und so sowohl die Daten wie auch die Prozeduren im gleichen Objekt zu vereinen und auch zu kapseln. Dies ermöglicht es Codes sehr viel besser zu strukturieren als dies in Modulen der Fall ist. So wird die Idee die man mit den Modulen und Prozeduren eingeführt hat weiterentwickelt. Ereignis-Orientiert: Auch die Ereignis gesteuerte Struktur erfüllt eine Aufgabe ohne welche moderne Programme schon alleine wegen ihrer Benutzeroberfläche nicht mehr zu lösen wäre. Zusammen mit dem im Objekt gebündelten Informationen können Ereignisse genau dann reagieren wenn sie auch gebraucht werden und erhalten alle Möglichkeiten und Informationen die sie dazu brauchen. Logik-Strukturierung: Durch Prozeduren lassen sich bereits logische Einheiten entwickeln die den Code einerseits besser organisieren und gleichzeitig lassen sich gut entwickelte Prozeduren universell nutzen. Durch OOP lassen sich logische Einheiten entwickeln die noch besser zusammenarbeiten können als dies bei normalen Prozeduren der fall ist. Während sozusagen in einem Standardmodul alle Eigenschaften verstreut in einer einzigen großen Kiste liegen, ist es in OOP möglich viele kleine Boxen zu Schafen und diese ineinander zu verschachteln.
Einige Nachteile lassen sich kaum umgehen. Geschwindigkeitsverlust und Speicherfragmentierung: Der größte und gleichzeitig kaum zu lösende Nachteil ist der Geschwindigkeitsverlust das durch das Management von Objekten (Instanzen und Reverenzen) zwangsläufig anfällt. Und das während der Laufzeit in der Regel viele Objekte nur sehr kurz existieren, also kurzzeitig erzeugt benutzt und wieder vernichtet werden, hat Geschwindigkeitsnachteile und führt zum Problem der Speicherfragmentierung. Will man dies vermeiden oder den Speicher aufräumen, kostet auch das wieder Ressourcen. (Das Betriebsystem muß dabei jedes mal Speicher reservieren und freigeben, und das OOP muß die Instanzen¦Referenzen erzeugen verwalten und wieder vernichten). Code-Reduktion: Eine Prozedur die in einem Standard- Modul deklariert wurde, innerhalb eines geschlossenen Projekts aber nie verwendet wird kann einfach beim Compilieren oder Linken weggelassen werden, das Programm wird dadurch kleiner. Falls Entwickler sich also eine große Funktionssammlung in ein einziges Standard- Modul zusammengefaßt haben um den Sprachumfang zu erweitern, werden beim Compilieren (einer EXE, nicht einer DLL) dennoch nur die Prozeduren eingefügt die auch wirklich benötigt werden. In einem Objekt ist dies nicht möglich, da nicht einfach Funktionen weggelassen werden können die zu einer Klasse gehören.
Hier nun die Nachteile, welche zT. Einfach durch saubere Programmierung umgangen werden können.
Polymorphie: Die Polymorphie birgt auch Nachteile in sich, die gerade durch die Vorteile entstehen, wenn man sie nicht gezielt einsetzt. Der Daten-Typ Variant ist das beste Beispiel dafür. Man sollte grundsätzlich nur da Variant verwenden wenn man ihn auch explizit benötigt. Das gilt auch für die polymorphen Codes. Da sie meistens nur zur Laufzeit auflösbar sind fallen jegliche Optimierungsmöglichkeiten weg, und zusätzlich fallen Verwaltungsaufgaben an, sie können also nie so schnell sein wie explizite Codes¦Daten-Typen. Auch wird durch Polymorphie die Typensicherheit unterlaufen. Kapselung: Die Kapselung eine der herausragenden Eigenschaften an Objekten, da sich so sehr viel effizienter Programme entwickeln lasen, und auch bestimmte Daten-Strukturen wie zB, Daten-Bäume nur mit Objekten wirklich sinnvoll programmieren lassen. Aber auch daraus entstehen wieder Nachteile. Deklaration: Die Kapselung macht es unmöglich das auch einige Variablen projektweit deklariert werden können, will man dies dennoch erreichen, muß man zusätzlich Standard-Module erzeugen die diese Variablen aufnehmen. Da es keine Interne Lösung für dieses Problem gib, unterlaufen solche Deklarationen die Objekt-Strategie, das Objekte all ihre Daten enthalten sollen. Namensvergabe: Da Programmierer einem Objekt ein beliebigen Namen vergeben können, tritt auch da das Problem der Lesbarkeit des Codes auf. Besonders schreibfaule Entwickler lassen sich gerade bei Objekten dazu hinreisen keine saubere Namensvergabe zu betreiben, da ja alles gekapselt ist und die Namensüberschneidung und dadurch der Zwang zu sinnvollen Namen nicht so stark ist. Der Weg zu den Informationen wird dadurch länger, weil man einem Objektname die Klasse nicht ansehen kann, bei Modulen hingegen sind Public-Namen projektweit immer die selben.
Referenzen: Ein weiteres Problem ist die saubere Organisation von Referenzen. Besonders in großen Projekten kann es durchaus zu Problemen kommen, wenn überall Objekt-Referenzen auf bestimmte Daten zugreifen und diese verändern können. Auch ist die saubere Zerstörung¦Löschung aller Objekte oft garnicht so leicht, vorallem wenn nicht strikt auf die Strukturierung des Programms geachtet wurde. So kann es sein das nicht alle Instanzen sauber gelöscht werden und verbleiben im Speicher, möglicherweise sogar nach Programmende. Ereignisse: Ereignisse und die nicht-lineare Programmierung führen in gewisser weise wieder ähnliche Probleme ein wie das frühere GoTo und die typischen Spaghetti-Codes. Es ist sehr leicht in einem Ereignisgeflecht den Überblick zu verlieren und schwer die Orientierung zu behalten was in einem größeren Programm genau zusammenhängt. Zudem steigt das Risiko für Zirkelschlüsse, in welchem Ereignisse wieder andere Ereignisse auslösen und sich so einfangen können. Und es fehlt grundsätzlich die Möglichkeit zB. beim Lesen¦Schrieben von Eigenschaften die Ereignisauslösung zu unterdrücken. Oft müssen Sicherheitsmaßnahmen solche Probleme durch zusätzliche Prüfungen verhindern (Ein gutes Beispiel ist eine TextBox: jede Textänderung löst ein Change Ereignis aus, dies wiederum fängt der Programmier ab und führt eine Eingabeprüfung durch und schreibt das Resultat wieder in die TextBox, worauf diese wieder ein Change Ereignis auslöst: Es findet dabei intern eine Prüfung statt ob sich tatsächlich der Text geändert hat, oder ob nur der gleiche Text zurückgeschrieben wurde, sonst wäre das ein fataler Zirkelschluß.). Grundsätzlich kann man das so zusammenfassen, das die Strukturen einerseits sehr viel besser organisiert sind durch die Kapselung und Bündelung zu Objekten. Andererseits können die logischen Strukturen auch komplexer und undurchschaubarer werden, schlicht durch die größeren Möglichkeiten und die Nicht-Linearität. Benötigt man einerseits gerade die erweiterten Möglichkeiten, muß man anderseits auch die Strukturen sauber aufbauen und sich der möglichen Probleme bewußt sein. Umgekehrt können Standard-Module durch das weglassen aller beschrieben Nachteile eine sichere und übersichtliche Umgebung schaffen, vorausgesetzt man berücksichtigt natürlich auch deren Nachteile. Vorallem bei kleinen Projekten sind Standard-Module oft ausreichend und zwingen zu projektweiten sinnvollen Namen.
Es gibt dadurch ganz bestimmte aufgaben die sehr gut in Standard-Modulen lösbar sind, und andere die nur sinnvoll in Objekten gelöst werden können. Dies hängt ab sowohl von der Logik-Struktur des Codes wie der Daten-Struktur. Die Entscheidung fällt dabei zwischen den Eigenschaften Ausführungsgeschwindigkeit, Speicherverbrauch und Anwendungsflexibilität, da sich diese meist gegenseitig widersprechen und deshalb nur eine der möglichen Optimierung gewählt werden kann.
Alles in Klassen? Leider gehen heute einige Entwickler davon aus das es besser ist alles in Klassen unterzubringen. So wurden in neueren Sprachen sogar die Standard-Typen in Klassen gepackt. Bei reinen Skript-Sprache macht dies auch Sinn, da so alle Variablen als Objekte auch ihre Daten tragen können und alle Daten im gleichen System verwaltet werden können. Bei Sprachen die compilierten Code erzeugen ist des aber durch die hohen Management Verluste von Objekten eher ein Nachteil. Um ein Beispiel zu nennen, wenn ein Objekt ein "Ball" ist hat er bestimmte Eigenschaften (Form, Größe, Material) bestimmte Methoden (Nehmen, Halten, Werfen) und kann Ereignisse auslösen (Auf Etwas Treffen, Energie weitergeben, Abprallen). Um die Atome und Moleküle hingegen aus dem der Ball besteht muß sich niemand (außer Physiker, "Compilerentwickler") kümmern. Sie sind zwar überall und bauen die ganzen Strukturen auf, müssen aber selbst nicht berücksichtigt werden um den Ball benutzen zu können. So ähnlich verhält es sich mit den Standard-Datentypen die sozusagen die Atome und Moleküle darstellen, also einfache strukturlose Daten welche fast alle direkt vom Prozessor untersetzt werden, überall verwendet werden, und selbst ihre Möglichkeiten mitbringen die eigentlich nicht speziell beschrieben und deklariert werden müssen. Es macht also sehr wohl auch heute noch Sinn einige Codes nicht als Klassen zu Entwickeln.
Standard-Modul: Als einfaches Beispiel, Funktionen die man als eine Funktionserweiterung zur Sprache betrachten kann und lineare Daten-Strukturen haben (nur eine einfache Dateneinheit oder möglicherweise ein Array) sind besser in Standard-Modulen zu lösen. Sie erzeugen projektweit gültige Namen und verwalten lineare oder einheitliche Daten. Zusammen mit der Möglichkeit Prozeduren zu überladen schaffen sie Einheitliche Namen und Prozesse (Überladung ist in VB6 leider nicht möglich.) Sie sind also auch besonders da gut geeignet wo es um universell nutzbare Prozeduren geht, welche man als Befehlserweiterungen der Sprache verstehen kann. Die Standard Datentypen ( Byte Integer Long Single Double usw.) mit Kassen zu umhüllen ist deshalb für compilierte Sprachen nicht effizient. Klassen-Modul: Logische Strukturen die in sich verschachtelt sind oder Datenstrukturen besitzen die verketten sind können viel effizienter mit Objekten gelöst werden. Sie bündeln dabei die Prozeduren zusammen mit ihren Daten und können so erstens viel leichter nach außen abgegrenzt werden und zweitens könne Logische Elemente ineinander verschachtelt werden. In Objekten ist sozusagen die Handlung mit den Daten verbunden. Was die Daten-Struktur angeht ist ein Tree (Datenbaum) ein gutes Beispiel da die einzelnen Knoten untereinander verbunden sind und eine nicht-lineare Daten-Struktur haben. Will man solche Daten-Strukturen in eine Lineare Form backen ist dies mit sehr viel mehr Aufwand verbunden und der Umgang wird komplizierter, da ein Knoten nicht seine eignen Daten mitbringt, müssen diese getrennt verwaltet werden, also in einem Array. Eine Liste wäre auch ein Beispiel, den anders als ein Array speichert eine Liste seine Daten nicht als einheitlichen Block im Speicher sondern kann die Daten auch verstreut ablegen, was zusätzliches Management benötigt. Ein weiterer Grund sind große Projekte in welchen viele Entwickler gleichzeitig abrieten. Durch die Kapselung ist es so möglich das sich die Entwickler nicht so sehr um die Namensvergabe und Konflikte mit möglichen Überschneidungen kümmern müssen. Und so unabhängig an bestimmten Aufgaben arbeiten können.
|