Vererbung & Super
Übersicht BlitzMax, BlitzMax NG Allgemein
wunderkindBetreff: Vererbung & Super |
Mo, März 28, 2005 17:06 Antworten mit Zitat |
|
---|---|---|
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 |
Mo, März 28, 2005 17:16 Antworten mit Zitat |
|
---|---|---|
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 |
Mo, März 28, 2005 17:27 Antworten mit Zitat |
|
---|---|---|
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 |
Mo, März 28, 2005 17:36 Antworten mit Zitat |
|
---|---|---|
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 |
Mo, März 28, 2005 17:40 Antworten mit Zitat |
|
---|---|---|
Welches Objekt genau existiert zu dem Zeitpunkt noch nicht? Local obj:tgameobject = New tgameobject wurde doch aufgerufen. | ||
wunderkind |
Mo, März 28, 2005 17:42 Antworten mit Zitat |
|
---|---|---|
Alles klar. Ich seh's. Augen auf. Danke. | ||
Demon |
Mo, März 28, 2005 17:44 Antworten mit Zitat |
|
---|---|---|
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 |
Mo, März 28, 2005 17:52 Antworten mit Zitat |
|
---|---|---|
Die verherige Create() (base type) initialisiert aber wichtige Daten. Muss das etwa ausgelagert werden? | ||
Nemesis |
Mo, März 28, 2005 17:56 Antworten mit Zitat |
|
---|---|---|
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 |
Mo, März 28, 2005 18:00 Antworten mit Zitat |
|
---|---|---|
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 |
Di, März 29, 2005 21:33 Antworten mit Zitat |
|
---|---|---|
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.
|
||
Dreamora |
Di, März 29, 2005 22:04 Antworten mit Zitat |
|
---|---|---|
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 |
Di, März 29, 2005 22:09 Antworten mit Zitat |
|
---|---|---|
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 |
Di, März 29, 2005 23:29 Antworten mit Zitat |
|
---|---|---|
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 |
Mi, März 30, 2005 9:10 Antworten mit Zitat |
|
---|---|---|
Ist das als 'Überschreiben des Operators new' zu verstehen? | ||
DivineDominion |
Mi, März 30, 2005 12:57 Antworten mit Zitat |
|
---|---|---|
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 Vielmehr ist das so eine Art Konstruktor ohne Parameter, oder so | ||
christian.tietze@gmail.com - https://christiantietze.de
macOS |
wunderkind |
Mi, März 30, 2005 14:12 Antworten mit Zitat |
|
---|---|---|
So meinte ich das . Schade, dass es keine echten Kontruktoren / Destruktoren gibt. | ||
Dreamora |
Mi, März 30, 2005 14:35 Antworten mit Zitat |
|
---|---|---|
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 |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
Übersicht BlitzMax, BlitzMax NG Allgemein
Powered by phpBB © 2001 - 2006, phpBB Group