Type erweitern mit anderem Type

Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Gehe zu Seite 1, 2  Weiter

Neue Antwort erstellen

Markus2

Betreff: Type erweitern mit anderem Type

BeitragDi, Dez 12, 2006 22:53
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragDi, Dez 12, 2006 23:03
Antworten mit Zitat
Benutzer-Profile anzeigen
dafür ist extends da Smile
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.

Markus2

BeitragDi, Dez 12, 2006 23:05
Antworten mit Zitat
Benutzer-Profile anzeigen
Hi,
so gehts nicht !?
Kommt dann Identifier "TAG" not found Sad

Local LbName:TGadget=CreateLabel("Name" ,0,0,48,24,PanPunkte)
LbName.Tag=""
 

Dreamora

BeitragDi, Dez 12, 2006 23:09
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragDi, Dez 12, 2006 23:21
Antworten mit Zitat
Benutzer-Profile anzeigen
hi,

geht auch nicht wirklich Sad
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

BeitragDi, Dez 12, 2006 23:26
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragDi, Dez 12, 2006 23:47
Antworten mit Zitat
Benutzer-Profile anzeigen
verstehe ich nicht Sad

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

BeitragMi, Dez 13, 2006 9:13
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragMi, Dez 13, 2006 12:22
Antworten mit Zitat
Benutzer-Profile anzeigen
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 Wink

Markus2

BeitragMi, Dez 13, 2006 19:37
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragMi, Dez 13, 2006 20:00
Antworten mit Zitat
Benutzer-Profile anzeigen
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 Wink

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

BeitragMi, Dez 13, 2006 20:22
Antworten mit Zitat
Benutzer-Profile anzeigen
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 Smile

Artemis

BeitragMi, Dez 13, 2006 21:32
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragMi, Dez 13, 2006 22:02
Antworten mit Zitat
Benutzer-Profile anzeigen
@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

BeitragMi, Dez 13, 2006 22:13
Antworten mit Zitat
Benutzer-Profile anzeigen
Nope,

dein Beispiel zeigt, dass du es doch nicht (so richtig) verstanden hast Wink.

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

BeitragMi, Dez 13, 2006 22:47
Antworten mit Zitat
Benutzer-Profile anzeigen
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 Smile
End Type

Artemis

BeitragDo, Dez 14, 2006 8:21
Antworten mit Zitat
Benutzer-Profile anzeigen
Markus2 hat Folgendes geschrieben:
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 .
So etwas müsstest du dir selber schreiben. Ala TGadgetInfo.Create(objekt:TGadget)
.

Markus2 hat Folgendes geschrieben:
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 .
Jo, und genau diesen CopyBefehl müsstest du selber schreiben.


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 habe jetzt mal sowas vorgeschlagen

Append Type TGadget
Field ... meine Smile
End Type
Ich glaube kaum, dass so etwas geht bzw. implementiert wird, aber vielleicht passiert das Unwahrscheinliche.

BladeRunner

Moderator

BeitragDo, Dez 14, 2006 8:50
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragDo, Dez 14, 2006 13:33
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragDo, Dez 14, 2006 14:32
Antworten mit Zitat
Benutzer-Profile anzeigen
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.

Gehe zu Seite 1, 2  Weiter

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group