Type erweitern mit anderem Type
Übersicht

![]() |
Markus2Betreff: Type erweitern mit anderem Type |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hi,
geht sowas ? Type TGadgetInfo Extends TGadget Field Tag:String End Type das soll das Type TGadget erweitern ohne das ich in das Gadget Modul eingreife . Und wenn ich jetzt ein Gadget erstelle was mir ein TGadget zurück gibt , will ich dann ein Feld "Tag" haben . |
||
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
dafür ist extends da ![]() |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
![]() |
Markus2 |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hi,
so gehts nicht !? Kommt dann Identifier "TAG" not found ![]() Local LbName:TGadget=CreateLabel("Name" ,0,0,48,24,PanPunkte) LbName.Tag="" |
||
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Jo das ist auch klar.
Du musst etwas vom Type TGadgetInfo erzeugen. Sonst existieren die Daten natürlich nicht, denn TGadget weiss nicht was deine extraklasse macht noch interessiert es sie. Du kannst jedoch local gadget:TGadget = new TGadgetInfo machen wenn du dann auf tag zugreifen willst, musst du einfach: TGadgetInfo(gadget).tag nutzen, also TGadget erst auf TGadgetInfo zurück casten, denn TGadget hat kein Tag. |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
![]() |
Markus2 |
![]() Antworten mit Zitat ![]() |
---|---|---|
hi,
geht auch nicht wirklich ![]() jetzt sagt er mir Attempt to access field or method of Null object wenn ich die Zeile mit Tag weg lasse sehe ich aber den Label Local LbName:TGadget=New TGadgetInfo LbName=CreateLabel("Name" ,0,0,48,24,PanPunkte) TGadgetInfo(LbName).Tag="" |
||
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Ein Label ist ein TGadget, kein TGadgetInfo
Die Originalklasse muss von TGadgetInfo sein, du kannst nicht aus einem TGadget ein TGadgetInfo machen wenn du nicht original aus einem TGadgetInfo ein TGadget gemacht hast. |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
![]() |
Markus2 |
![]() Antworten mit Zitat ![]() |
---|---|---|
verstehe ich nicht ![]() Dieses Extends sorgt doch dafür das das TGadgetInfo die gleichen Eigenschaften hat wie TGadget + meine eigenen oder ? Also warum kann BlitzMax dann nicht diese Struktur füllen mit den TGadget Daten ??? Edit: So geht es , aber es ist doof die Felder selber zu kopieren ... Code: [AUSKLAPPEN] Type TA Field x:Int Field y:Int End Type Type TB Extends TA Field Tag:String End Type Local Test:TB=New TB Local X:TA=New TA x.x=1 x.y=2 Test.x=X.x Test.y=X.y DebugLog Test.x DebugLog Test.y DebugLog Test.Tag |
||
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Du musst sie auch nicht selbst kopieren.
Wenn du etwas vom Typ TB erzeugst sind alle Felder von TA + die Felder von TB enthalten. Beim Gadget ist es jedoch so, dass CreateLabel oder alle MaxGUI Befehle NUR TGadget erzeugen und nicht TGadgetInfo (wäre wie wenn du hier nur TA erzeugen würdest). Damit TB Felder enthalten sein und genutzt werden können, muss das Objekt bzw die Referenz vom Typ TB (TGadgetInfo) sein, ansonsten sind nur die TA Felder enthalten, wenn du das TB einem TA zuweist (was geht, weil ein TB ja ein TA + Zusatz ist) Es ist jedoch nie und unter garkeinen Umständen möglich aus etwas, was als TA erzeugt worden ist, ein TB zu machen und dadurch neue Felder zu erhalten, weil TA diese Daten ganz einfach nie enthielt und somit auch nicht nutzen kann. Denn Type Casting verändert nicht das Objekt! Es ändert nur den Type der Referenz |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
![]() |
Jolinah |
![]() Antworten mit Zitat ![]() |
---|---|---|
Oder anhand von einfacheren Objekten erklärt:
Code: [AUSKLAPPEN] Type Frucht
Field Farbe:Int End Type Type Kirsche extends Frucht Field Kern:Int End Type Local f:Frucht = new Kirsche 'funktioniert, da eine Kirsche eine Frucht ist Local k:Kirsche = new Frucht 'funktioniert nicht Eine Frucht-Variable kann jegliches Frucht-Objekt enthalten. Jedes Objekt das also von Frucht geerbt hat ist nun auch eine Frucht und kennt das Farbe-Attribut, hat aber seine eigenen speziellen Attribute wie Kern etc. Umgekehrt geht das aber nicht. Allgemein gesehen muss nämlich eine Frucht nicht zwingend eine Kirsche sein, sondern kann alles mögliche sein. Deswegen kann man bei einer Frucht auch nicht davon ausgehen dass sie einen Kern hat. Die Variable vom Type Kirsche erwartet aber einen Kern... also geht das nicht ![]() |
||
![]() |
Markus2 |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hi ihr ,
Type Frucht Field Farbe:Int End Type Type Kirsche Extends Frucht Field Kern:Int End Type Local f:Frucht = New Kirsche 'funktioniert, da eine Kirsche eine Frucht ist f.kern=1 <??? das geht aber nicht Blitz sagt mir identifier Kern nicht gefunden !??? Zitat: Eine Frucht-Variable kann jegliches Frucht-Objekt enthalten. Jedes Objekt das also von Frucht geerbt hat ist nun auch eine Frucht und kennt das Farbe-Attribut, hat aber seine eigenen speziellen Attribute wie Kern etc. |
||
![]() |
Jolinah |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hi,
Ja das geht so leider nicht. Die Frucht kennt Kern nicht, das Objekt selber wie es sich im Speicher befindet hat aber den Kern. Damit du auf den Kern zugreifen kannst musst du die Frucht wieder in eine Kirsche konvertieren. Hab das wahrscheinlich in dem zitierten Satz etwas unklar formuliert ![]() Code: [AUSKLAPPEN] Local f:Frucht = new Kirsche 'Kirsche (im Speicher) mit Frucht-Variable angesprochen
f.Farbe = $FFFF0000 Local f2:Frucht = new Frucht 'Allgemeine Frucht f2.Farbe = $FFFFFF00 Local k:Kirsche = Kirsche(f) 'Kirsche mit Kirsche-Variable angesprochen - funktioniert Local k2:Kirsche = Kirsche(f2) 'Funktioniert nicht! Weil es nie eine Kirsche war. Das entscheidende ist eigentlich: Alles was mit New erstellt wird bleibt im Speicher auch genau so bestehen. Erweiterte Types können aber auch mit Variablen vom Basistype angesprochen werden, diese Variable kennt dann aber auch nur die Attribute des Basistypes. Diese Vorgehensweise macht wohl am meisten Sinn im Zusammenhang mit Methoden: Code: [AUSKLAPPEN] Type Gadget
Method Move(x:Int, y:Int) _x = x _y = y End Method End Type Type Button Extends Gadget Method Move(x:Int, y:Int) _x = _Parent._x + x _y = _Parent._y + y End Method End Type Local list:TList = new TList Local b:Button = new Button Local g:Gadget = new Gadget list.AddLast(b) list.AddLast(g) For Local tmp:Gadget = EachIn list tmp.Move(10, 10) Next In dem Foreach-Loop werden dann alle Gadgets als normale Gadgets angesprochen, auch wenn die Liste zum Teil erweiterte Objekte enthält. Bei den erweiterten Objekten kann man die Methoden überschreiben und sie etwas ganz anderes tun lassen als das Basis-Objekt. Es wird dann für jedes Objekt die richtige Methode aufgerufen, wichtig ist ja nur dass der entsprechende Type die Methode kennt. |
||
![]() |
Markus2 |
![]() Antworten mit Zitat ![]() |
---|---|---|
ist alles schei*e weil wenn ich jetzt das hier habe geht es nicht mehr
f:Frucht=new Kirsche rf:Frucht=new Frucht f=rf dann geht Kirsche(f).Kern=1 nicht mehr Mir ging es darum diese TGadget Struktur zu erweitern das ich da eigene Felder unterbringen kann und wenn ich jetzt TGadget zuweisen würde wäre dann auch TGadgetInfo hinüber . Und TGadgetInfo=TGadget geht nicht *GRRR* obwohl in TGadgetInfo > TGadget enthalten ist . EDIT: ich habe es mal auf der .com Seite erwähnt wie es möglich sein könnte ohne das ich da jetzt drum rum arbeiten muß . Alternative wäre eine Struktur wo ich mir das Gadget drin merke . Was dann aber doof ist wenn ich die Kids von einem Panel durch gehen muß , weil dann muß ich mir wieder aus meiner Liste das Gadget raus kramen um Zusatz Infos zu bekommen . danke euch trotzdem ![]() |
||
![]() |
Artemis |
![]() Antworten mit Zitat ![]() |
---|---|---|
Du hast scheinbar den Sinn und die Funktion von Vererbung noch nicht begriffen.
In diesem OOP-Tutorial von Jolinah ist Vererbung eigentlich ganz gut erklärt, auch in diversen Lernbüchern ((fast) völlig egal welche Sprache). |
||
![]() |
Markus2 |
![]() Antworten mit Zitat ![]() |
---|---|---|
@Artemis
ich denke schon das ich es verstanden habe . Ich habe eine erweiterte Struktur die eine andere beinhaltet . Kann also alle Werte setzen und lesen . Wenn ich jetzt aber eine einfache Struktur der erweiterten zuweise gehen meine erweiterten Eigenschaften flöten bzw. sagt mir der Compiler das er TGadget nicht in TGadgetInfo rein kopieren kann was quatsch ist und umwandeln will er es auch nicht und blubbert was von ist NULL !? Also das muß gehen , geht aber nicht Type TGadgetInfo Extends TGadget Field Tag:String End Type Local LbName:TGadgetInfo =New TGadgetInfo LbName=TGadgetInfo(CreateLabel("Name" ,0,0,48,24,PanPunkte)) LbName.Tag="" wenn du MaxGUI hast versuche es mal in der Art ! |
||
![]() |
Artemis |
![]() Antworten mit Zitat ![]() |
---|---|---|
Nope,
dein Beispiel zeigt, dass du es doch nicht (so richtig) verstanden hast ![]() Code: [AUSKLAPPEN] Type Frucht
Field Farbe:String Field Form:String EndType Type Apfel Extends Frucht Field KernAnzahl:Int EndType Wenn du jetzte einen Apfel erstellst, kannst du ihn auch als Frucht behandeln, da er ja eine ist (Apfel Extends Frucht ≈ Apfel ist eine Frucht (aber noch mehr)). Wenn du jetzt aber eine neue Frucht erstellst, kannst du sie nicht als Apfel behandeln, da eine Frucht zwar ein Apfel sein kann (dann muss sie aber als Apfel erstellt worden sein) aber nicht zwingend ist. Genauso ist es mit deinem TGadget und dem TGadgetInfo. Jedes TGadgetInfo ist auch ein TGadget, aber nicht jedes TGadget ein TGadgetInfo. Woher soll ein als TGadget erstelltes Objekt auf einmal die neues Eigenschaften, die bei TGadgetInfo definiert wurden, herbekommen? |
||
![]() |
Markus2 |
![]() Antworten mit Zitat ![]() |
---|---|---|
Das Programm sagt doch was was ist .
Wenn TGadgetInfo Null ist und ich ein TGadget zuweise soll ein TGadgetInfo erstellt werden (was ich auch selber vorher könnte) , das TGadget da rein kopiert werden und dann kann TGadget auf dem Müll wenn es nicht mehr gebraucht wird . Wenn TGadgetInfo nicht Null ist und ich ein TGadget zuweise werden nur die Daten von TGadget da rein kopiert werden und dann kommt TGadget auf dem Müll wenn es direkt übergeben wurde wie es bei CreateLabel der Fall ist . Das TGadget hat sich auch nicht um die anderen Eigenschaften zu kümmen weil ich die ja selber setzen will . Eigentlich fehlt nur ein Copybefehl für die Strukturdaten das TGadget in ein TGadgetInfo Exdends TGadget kopiert wird , mehr nicht . Normal müßte ich mit TGadgetInfo(TGadget) eine wandlung machen können was aber auch nicht geht . Die schei* Eigenschaften sollen einfach nur leer sein wenn ich ein TGadget in ein TGadgetInfo umwandle . Eigentlich will ich ein TGadget mit zusatz Eigenschaften die ich nur nicht in dem Gui Modul unterbringen will . Dann könnte ich ja direkt TGadget erweitern . Immer wenn TGadget benutzt wird soll es dann so sein wie vorher + meine Struktur haben . Zitat: Genauso ist es mit deinem TGadget und dem TGadgetInfo. Jedes TGadgetInfo ist auch ein TGadget, aber nicht jedes TGadget ein TGadgetInfo. Woher soll ein als TGadget erstelltes Objekt auf einmal die neues Eigenschaften, die bei TGadgetInfo definiert wurden, herbekommen? EDIT: ich habe jetzt mal sowas vorgeschlagen Append Type TGadget Field ... meine ![]() End Type |
||
![]() |
Artemis |
![]() Antworten mit Zitat ![]() |
---|---|---|
Markus2 hat Folgendes geschrieben: Das Programm sagt doch was was ist .
So etwas müsstest du dir selber schreiben. Ala TGadgetInfo.Create(objekt:TGadget)
Wenn TGadgetInfo Null ist und ich ein TGadget zuweise soll ein TGadgetInfo erstellt werden (was ich auch selber vorher könnte) , das TGadget da rein kopiert werden und dann kann TGadget auf dem Müll wenn es nicht mehr gebraucht wird . . Markus2 hat Folgendes geschrieben: Wenn TGadgetInfo nicht Null ist und ich ein TGadget zuweise
Jo, und genau diesen CopyBefehl müsstest du selber schreiben.
werden nur die Daten von TGadget da rein kopiert werden und dann kommt TGadget auf dem Müll wenn es direkt übergeben wurde wie es bei CreateLabel der Fall ist . Das TGadget hat sich auch nicht um die anderen Eigenschaften zu kümmen weil ich die ja selber setzen will . Eigentlich fehlt nur ein Copybefehl für die Strukturdaten das TGadget in ein TGadgetInfo Exdends TGadget kopiert wird , mehr nicht . Markus2 hat Folgendes geschrieben: Normal müßte ich mit TGadgetInfo(TGadget) eine wandlung machen können was aber auch nicht geht . Nö, da es dem Sinn der Vererbung widerspricht, Basis-Typen als spezifizierte Typen zu behandeln.
Markus2 hat Folgendes geschrieben: Die schei* Eigenschaften sollen einfach nur leer sein wenn ich ein TGadget in ein TGadgetInfo umwandle . So etwas lässt sich mit (meines Wissens) keiner Sprache bewerkstelligen, und wenn überhaupt dann wahrscheinlich auf Umwegen.
Markus2 hat Folgendes geschrieben: EDIT:
Ich glaube kaum, dass so etwas geht bzw. implementiert wird, aber vielleicht passiert das Unwahrscheinliche.
ich habe jetzt mal sowas vorgeschlagen Append Type TGadget Field ... meine ![]() End Type |
||
![]() |
BladeRunnerModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Es gibt einen ganz einfachen Grund weshalb das was Du willst so nicht geht (und auch nicht gemacht werden sollte).
Stell dir mal vor du leitest 2 Types von deiner Basis ab: Code: [AUSKLAPPEN] type basis
field bla end type type a extends basis method do() print a*a end method end type type b extends basis method do() print a+a end method end type Wenn Du nun - wie du es versuchst - von der Basis auf einen der Erben zu schliessen, so muss das in die Hose gehen, denn der Compiler kann ja nicht wissen welchen der Erben du meinst. Das Ergebnis ist also undefiniert. Soll a nun addiert oder multipliziert werden ? Das ist der Grund warum sich jede Programmiersprache da quer stellt. Die Kinder wissen von der Basis, aber umgekehrt ist dem nicht so. Es könnte ja x Erben geben von denen die Basius nix weiss. (Im Speichermanagment sieht das so aus dass für Basis nur der Speicher alloziert wird den es auch tatsächlich braucht, also kann es auch die "Mehrinformation" nicht aufnehmen. Das ist auch sinnig, denn je nachdem wieviele Erben es gäbe müssten ja Massen an unnützem Speicher belegt werden, und oft wäre (s.o.) keine Eindeutigkeit gegeben. Was Du tun kannst, ist dein TGadgetinfo zur Basis machen und es um TGadget extenden. oder Du erschaffst dir einen TGadgetinfo und machst das Gadget darin als field, dann hast du den Zugriff auch, wenn auch eine Ebene tiefer (das wäre dann dein 'append'). Aber so vererben wie Du es wolltest, das geht nicht. |
||
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3 Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64 B3D BMax MaxGUI Stolzer Gewinner des BAC#48, #52 & #92 |
![]() |
Markus2 |
![]() Antworten mit Zitat ![]() |
---|---|---|
Was ich brauche könnte so aussehen
Type TGadget Fields von BlitzMax Include meineGadetFields.bmx End Type da ich das GUI Modul aber nicht verändern will hatte ich sowas vorgeschlagen Append Type TGadget Fields von Mir End Type und der Compiler sollte da das draus machen Type TGadget Fields von BlitzMax Fields von Mir End Type oder TGadget müßte die Funktionen haben wie z.B. CreateLabel etc. was dann so aussähe TGadget.CreateLabel dann könnte ich so arbeiten Type TGadgetEx Extends TGadget Fields von Mir End Type Local G:TGadgetEx =new TGadgetEx G=TGadgetEx.CreateLabel Diese Idee hatte ich auch schon , finde ich aber nicht so toll Type TGadgetEx Field G:TGadget Fields von Mir End Type |
||
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Append macht keinen Sinn, da dann TGadget nicht mehr TGadget wäre, womit der ganze Sinn hinter typsicheren Sprachen flöten wäre.
TGadgetEx ist eine Variante das ganze zu lösen. (in diesem Falle die einfachere, da die originalklassen stark C basierend sind) Eine andere ist halt, alle Konstruktoren auch für dein TGadgetInfo zu implementieren (also erzeugt intern in der Funktion ein TGadgetInfo, befüllt es mit den Daten von TGadget und gibt dann ein auf TGadget heruntergecastetes TGadgetInfo zurück), dann geht das auch. Bedeutet aber einen entsprechenden Mehraufwand. Einer der Hauptvorteile von Vererbung ist es, das Extend zu nutzen um "Basisklassen" festlegen zu können (zb für ein Field in einer anderen Klasse, wo du gemäss oberem Beispiel Frucht nehmen würdest, dann aber auch apfel, birne etc anhängen kannst). Jetzt mal davon abgesehen, dass man Methoden, die identisch sind, nicht zig mal neu schreiben muss wie das in Blitz3D zb noch der Fall ist. |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group