Vererbung & Super

Übersicht BlitzMax, BlitzMax NG Allgemein

Neue Antwort erstellen

wunderkind

Betreff: Vererbung & Super

BeitragMo, März 28, 2005 17:06
Antworten mit Zitat
Benutzer-Profile anzeigen
Moin,

kleines Problem. Ich habe mehrere Types und möchte sie beerben. Aber: die neuen extended Types sollen eine Funktion kennen, die (zwangsweise) den gleichen Namen wie eine aus dem Basis-Type. Überschrieben werden soll die Funktion nicht. Ich habe einfach ganz frech Super.function_abc() verwendet. Kein Syntaxfehler. Dafür schmiert mir das Programm mit Exception ab. Bug?

Wie kann ich das Problem geschickt umgehen?
 

Demon

BeitragMo, März 28, 2005 17:16
Antworten mit Zitat
Benutzer-Profile anzeigen
Hm, bei mir geht folgendes:

Code: [AUSKLAPPEN]
Type BaseType
   Function HalloWelt()
      Print "Hallo"
   EndFunction
EndType

Type ExtType Extends BaseType
   Function HalloWelt()
      Super.HalloWelt()
      Print "Welt"
   EndFunction
EndType


ExtType.HalloWelt()


Ist das so, wie du meintest oder hab ich was falsch verstanden?
Don't drink and derive!

wunderkind

BeitragMo, März 28, 2005 17:27
Antworten mit Zitat
Benutzer-Profile anzeigen
Im Grunde mache ich das genauso. Hier mal die beiden beispielhaften code snippets:

Code: [AUSKLAPPEN]
Type tgameobject
   Field xpos : Int
   Field ypos : Int
   Field xvel : Int ' x velocity
   Field yvel : Int ' y velocity
   Field xspeed : Int
   Field yspeed : Int
   Field sprite : tsprite

   ' -----------------------------------
   Function create:tgameobject()
      Local obj:tgameobject = New tgameobject

      obj.sprite.create()

      Return obj
   End Function

End Type


Code: [AUSKLAPPEN]
Type tplayer Extends tgameobject
   ' -----------------------------------
   Function create:tplayer()
      Super.Create()

      Local obj:tplayer = New tplayer

      Return obj
   End Function
End Type


Im Programm wird dann nur Global plr:tplayer = tplayer.create() aufgerufen. Und *zack* Exception.
 

Demon

BeitragMo, März 28, 2005 17:36
Antworten mit Zitat
Benutzer-Profile anzeigen
Ja, klar, dass da ein Memory Fehler kommt.
In der Zeile mit "obj.sprite.create()" ist das offensichtlich (für den Compiler) eine Methode, die du aufrufst, das Objekt existiert aber noch gar nicht.
Abgesehen davon ist die create-Funktion im Basistypen sowieso verschwendet, da sie einfach so ins Nichts läuft (wird nicht gespeichert).

[Edit]
So würde das zum Beispiel funktionieren, wenns auch nicht mehr Sinn hätte:

Code: [AUSKLAPPEN]
Type MyObj
   Function create:MyObj()
      Return New MyObj
   EndFunction
EndType

Type tgameobject
   Field xpos : Int
   Field ypos : Int
   Field xvel : Int ' x velocity
   Field yvel : Int ' y velocity
   Field xspeed : Int
   Field yspeed : Int
   Field sprite : MyObj

   ' -----------------------------------
   Function create:tgameobject()
      Local obj:tgameobject = New tgameobject

      obj.sprite = MyObj.create()

      Return obj
   End Function

End Type

Type tplayer Extends tgameobject
   ' -----------------------------------
   Function create:tplayer()
      'Sinnlos hier, da das Ergebnis beim Verlassen der Funktion weg ist.
      Super.Create()

      Local obj:tplayer = New tplayer

      Return obj
   End Function
End Type

Global plr:tplayer = tplayer.create()
Don't drink and derive!
  • Zuletzt bearbeitet von Demon am Mo, März 28, 2005 17:41, insgesamt einmal bearbeitet

wunderkind

BeitragMo, März 28, 2005 17:40
Antworten mit Zitat
Benutzer-Profile anzeigen
Welches Objekt genau existiert zu dem Zeitpunkt noch nicht? Local obj:tgameobject = New tgameobject wurde doch aufgerufen.

wunderkind

BeitragMo, März 28, 2005 17:42
Antworten mit Zitat
Benutzer-Profile anzeigen
Alles klar. Ich seh's. Augen auf. Danke.
 

Demon

BeitragMo, März 28, 2005 17:44
Antworten mit Zitat
Benutzer-Profile anzeigen
Das Objekt mit dem Namen "Sprite" und dem Typen "tsprite" aus der create-Funktion des Basistypen existiert noch nicht (du wolltest es ja wahrscheinlich gerade 'createn').
Anstatt die Funktion aufzurufen, rufst du eine Methode auf.
Don't drink and derive!

wunderkind

BeitragMo, März 28, 2005 17:52
Antworten mit Zitat
Benutzer-Profile anzeigen
Die verherige Create() (base type) initialisiert aber wichtige Daten. Muss das etwa ausgelagert werden?
 

Nemesis

BeitragMo, März 28, 2005 17:56
Antworten mit Zitat
Benutzer-Profile anzeigen
nein.

das problem bei dir ist nur das du im base type mit
Code: [AUSKLAPPEN]

obj.sprite.create()


eine methode eines objektes aufrufst das noch garnicht existiert.
vermutlich meintest du
Code: [AUSKLAPPEN]

obj.sprite = tsprite.create()
 

Demon

BeitragMo, März 28, 2005 18:00
Antworten mit Zitat
Benutzer-Profile anzeigen
Hm, gute Frage; ich denke schon, dass du eine Funktion schreiben musst, die nur die Werte setzt, weil du sonst das falsche Objekt zurückbekommst.
Sowas in der Art meine ich:

Code: [AUSKLAPPEN]
Type MyObj
   Function create:MyObj()
      Return New MyObj
   EndFunction
EndType

Type tgameobject
   Field xpos : Int
   Field ypos : Int
   Field xvel : Int ' x velocity
   Field yvel : Int ' y velocity
   Field xspeed : Int
   Field yspeed : Int
   Field sprite : MyObj

   ' -----------------------------------
   Function create:tgameobject()
      Local obj:tgameobject = New tgameobject
     
      SetValues(obj)

      Return obj
   End Function
      
      Function SetValues(Obj:tgameobject) Private   
         'Test   
         obj.xpos = 13
         obj.sprite = MyObj.create()
      EndFunction

End Type

Type tplayer Extends tgameobject
   Field NewInfo:String
   
   ' -----------------------------------
   Function create:tplayer()

      Local obj:tplayer = New tplayer
     
      SetValues(obj)
     
      obj.NewInfo = "Neue Informationen"

      Return obj
   End Function
End Type

Global plr:tplayer = tplayer.create()

Print plr.NewInfo
Print plr.xpos


[Edit]
@Nemesis: Die Create-Funktion des Basistypen liefert aber doch eine Referenz auf ein nicht-konvertierbares Objekt des Basistypen zurück, kann also so einfach nicht gespeichert werden.
Damit würde die Funktion ins Leere gehen, die globale Initialisierung, die allen abgeleiteten Objekten des Basistypen gemein ist, kann also nicht in der Create-Funktion stattfinden, da diese wie gesagt den Basistypen zurückgibt.
Deshalb muss die Funktion meiner Meinung nach ausgelagert werden, aber vielleicht fällt dir was besseres ein?
Don't drink and derive!

wunderkind

BeitragDi, März 29, 2005 21:33
Antworten mit Zitat
Benutzer-Profile anzeigen
Um eine gewisse Konsistenz im Code zu halten, würde ich allen Objekten eine solche Init-Funktion verpassen. Problem: Beerbende Objekte müsste die Funktion überschreiben, können sie aber nicht, da der Typ des Parameters natürlich immer abweicht, nämlich immer der Typ des jeweiligen Objekts ist.

Rolling Eyes
 

Dreamora

BeitragDi, März 29, 2005 22:04
Antworten mit Zitat
Benutzer-Profile anzeigen
Unterschiedliche Typen sind egal, zumindest hat der compiler nix dagegen und läuft problemlos ... vorausgesetzt natürlich, der Grundtype besteht nur aus abstract methods / functions ...

Aber das setz ich eigentlich voraus, da man sonst bei import ziemlich schnell in eine massive wand rennt wegen selbstimports.


Code: [AUSKLAPPEN]

type SceneNode abstract
  ' Typedeklaration zur einbindung in andere klassen
  function make:SceneNode () abstract

end type

type Entity extends SceneNode
  'eine mögliche Implementation von SceneNode
  function make:Entity ()
    return new Entity
  end function

end type
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.

wunderkind

BeitragDi, März 29, 2005 22:09
Antworten mit Zitat
Benutzer-Profile anzeigen
Auf diese Art würde ich doch aber nur einen toten Type produzieren!? Eine Hülle quasi. Meine Landgänge auf OO-Island sind zugegebener Weise schon ewig her.
 

Dreamora

BeitragDi, März 29, 2005 23:29
Antworten mit Zitat
Benutzer-Profile anzeigen
Ja du erzeugst eine "Definition" die selbst noch keinen Zweck hat.

Aber die kannst du in jeder anderen Klasse verwenden als ob sie existieren würde.
Du musst nur der entsprechenden Funktion den extended Type zuweisen, der die implementationen enthält.

Vorteil davon ist, dass du 1 Type hast den du im Code einfügst, aber beliebig viele Implementationen der Funktionalität, die du nach Bedarf auswechseln kannst (deswegen habe ich Fields / const auch im Grundtype. GLOBALS nie in den Grundtype, da diese dann einmalig für ALLE verschiedenen extended sind und das ist meist sehr sehr unpässlich und man findet damit verbundene Bugs kaum wenn man nicht danach sucht.

Ach ja und zur initialisierung von statischen Daten gibt es auch noch:

Method new()

end method


die wird rekursiv durch den gesammten HierarchyTree vom "Urobjekt" bis runter zur extended aufgerufen wenn ein extended objekt erzeugt wird.

Code: [AUSKLAPPEN]

Type test

   Method New()
    Print "yehaaa"
   End Method
   
End Type


Type trala Extends test
   Method New ()
    Print "trala"
   End Method
   
End Type


Local a:trala = New trala
Delay
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.

wunderkind

BeitragMi, März 30, 2005 9:10
Antworten mit Zitat
Benutzer-Profile anzeigen
Ist das als 'Überschreiben des Operators new' zu verstehen?

DivineDominion

BeitragMi, März 30, 2005 12:57
Antworten mit Zitat
Benutzer-Profile anzeigen
Hmm, ja oder nein zu sagen ist da ne Gratwanderung - wenn du die Methode änderst, wird bei 'New Type' auch diese Methode aufgerufen. Der Operator selber ändert sich ja aber nicht Smile Vielmehr ist das so eine Art Konstruktor ohne Parameter, oder so
christian.tietze@gmail.com - https://christiantietze.de
macOS

wunderkind

BeitragMi, März 30, 2005 14:12
Antworten mit Zitat
Benutzer-Profile anzeigen
So meinte ich das Wink. Schade, dass es keine echten Kontruktoren / Destruktoren gibt.
 

Dreamora

BeitragMi, März 30, 2005 14:35
Antworten mit Zitat
Benutzer-Profile anzeigen
Konstruktoren / Destruktoren wären was schönes ... aber alleine schon Parameter Overriding wäre sinnvoll, vor allem für math module.

also das man in Vektor zb

add (other:Vector)
add (x:double,y:double)

etc machen könnte. Und ohne das wirds nix mit Konstruktoren.


Destruktoren hast du doch ...

Auch bekannt als

method delete ()

end method

Smile
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group