Polymorphismus mit dem TeamDeveloper

Mit dem TeamDeveloper ist objektorientierte Programmierung möglich. Eingesetzt werden dafür die Functional Classes, auch UDV (user defined variable) genannt. Dabei werden folgende Features unterstützt:

  • mehrfache Vererbung (Klasse3 ist abgeleitet von Klasse2, diese ist abgeleitet von Klasse1, …)
  • multiple Vererbung (von mehr als einer Basisklasse gleichzeitig ableiten)
  • Methoden überschreiben
  • Destruktor

Leider gibt es keinen Konstruktor. Private Variablen und Methoden können ebenfalls nicht deklariert werden, alles ist public.

Nicht ganz so offensichtlich ist, dass mit den UDVs auch Polymorphismus möglich ist.

Beispiel:

Klasse „Vehicle“ fungiert als Basisklasse und stellt eine Methode namens „GetType()“ zur Verfügung. Diese liefert den String „vehicle“ zurück.

Klasse „Car“ leitet von „Vehicle“ ab und implementiert ebenfalls die Methode „GetType()“. Diese liefert den String „car“.

Functional Class: Vehicle
 Functions
  Function: GetType
   Description:
   Returns
    String:
   Actions
    Return 'Vehicle'

Functional Class: Car
 Derived From
  Class: Vehicle
 Functions
  Function: GetType
   Returns
    String:
   Actions
    Return 'Car'

Erstellt man eine Liste (Array) von Vehicles, kann man mithilfe des new Operators einzelnen Elementen des Arrays eine spezifische, von Vehicle abgeleitete Klasse zuweisen.

Function: Main
 Local variables
  FunctionalVar: aVehicles[*]
   Class: Vehicle
  String: sOut
  Number: nCountVehicles
  Number: nIdx
 Actions
  Set aVehicles[0] = new Vehicle
  Set aVehicles[1] = new Car
  Call SalArrayGetUpperBound( aVehicles, 1, nCountVehicles )
  While (nIdx <= nCountVehicles )
   If ( sOut )
    Set sOut = sOut || '
      '
   Set sOut = sOut || 'Vehicle ' || SalNumberToStrX( nIdx, 0 ) || ' is a '
                   || aVehicles[nIdx].GetType()
   Set nIdx = nIdx + 1
  Call SalMessageBox( sOut, 'Vehicles', MB_Ok )

Leider ist das Ergebnis noch nicht wie gewünscht:

Polymorphism_naive

Polymorphism_naive

In Zeile 2 sollte „Vehicle 1 is a Car“ stehen, da dem zweiten Arrayelement mit „Set aVehicles[1] = new Car“ die Car-Klasse zugeordnet wurde. Offensichtlich wird aber die Methode GetType() der Basisklasse Vehicle gerufen – ist ja auch klar, schließlich ist der Datentyp des Array „Vehicle“ und nicht „Car“.

In anderen Programmiersprachen wie z.B. C++ oder C# gibt es für solche Fälle das Schlüsselwort virtual für die überschreibbare Methode in der Basisklasse und override für die überschriebene Methode in der abgeleiteten Klasse.

Übrigens: Die Zeile „Set aVehicles[0] = new Vehicle“ ist natürlich nicht notwendig – sie ist hier nur zur Verdeutlichung angeführt.

Wie geht das trotzdem im TeamDeveloper?

Indem man den sogenannten LateBind-Operator .. innerhalb der Klasse verwendet. Die „eigentliche Funktion“, die die Arbeit erledigt wird dazu mit dem Präfix __ (doppelter Unterstrich) versehen (Konvention – könnte auch anders heißen). Die nach außen sichtbare Funktion „GetType()“ ruft die „private“ Funktion __GetType() – allerdings mit dem LateBind-Operator .. (zwei Punkte). Dieser sorgt dafür, dass die _GetType()-Funktion der davon abgeleiteten Klasse gerufen wird, sofern sie dort implementiert wurde. Ist das nicht der Fall, wird natürlich die von Vehicle gerufen.

Das sieht dann so aus: 

Functional Class: Vehicle
 Functions
  Function: __GetType
   Returns
    String:
   Actions
    Return 'Vehicle'
  Function: GetType
   Returns
    String:
   Actions
    Return ..__GetType()

 Bei der Car-Klasse gibt es nur eine Änderung: Die Funktion „GetType()“ bekommt das Präfix __.

Zur Information: Im TeamDeveloper werden Variablen und Funktionsnamen, die mit zweifachem Unterstrich eingeleitet werden, im Coding Assistant nicht angezeigt bzw. vorgeschlagen. Sie sind also quasi „ein bisschen“ privat. Siehe dazu auch die TD-Hilfe unter dem Stichwort „Active Coding Assistant tab“.

Jetzt wird gewünschte Ergebnis erzielt:

Polymorphism_TeamDeveloper

Polymorphism_TeamDeveloper

Wofür ist das nützlich? Meines Erachtens gibt es eine ganze Reihe von Anwendungsfällen. Und zwar immer dann, wenn man Informationen verarbeiten muss, die zur Compile-Zeit noch nicht bekannt sind. Im nächsten Artikel wird diese Technik verwendet, um den Dateninhalt einer beliebigen Datenbanktabelle im XML-Format zu serialisieren.Happy Coding!

Advertisements

Über thomasuttendorfer
Ich bin Entwicklungsleiter bei der Softwarefirma [ frevel & fey ] in München. Wir entwickeln Business-Software für Verlage und verwenden dafür den Gupta Team-Developer sowie Visual Studio.

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s

%d Bloggern gefällt das: