Inheritance and Globals / Methods which use them

BlitzMax Forums/BlitzMax Programming/Inheritance and Globals / Methods which use them

Gabriel(Posted 2006) [#1]
I'm writing a GUI module ( think I mentioned this already, but just in case ) and I'm thinking that I can save a lot of code and make things more readable by having a base gadget type and extending it for each specific gadget type.

The thing is, the gadgets rely on a bunch of type-globals. Things like the texture they draw from, I can't have those as a field instead. But if they're globals, I can't inherit them because then I end up with one for all gadget types, when what I need is one for *each* gadget type ( and *not* one for each gadget instance! )

Now that's ok as far as it goes, but I find that a lot of my methods are using those globals in some shape or form, which means that I can't inherit any of those methods either. It's ending up so that about half the stuff which every gadget has in common can't be done through inheritance because it uses one or more globals. It's a royal pain.

Now I'm fairly new to OO programming, so is it my way of thinking that's wrong? How should I be thinking? Is it someting which BMax does not have which other OO languages do have? Is there another way of achieving the same thing?

It seems ( to an OO newbie like myself ) that being able to mark Globals as abstract so that the inherited methods know that they exist but doesn't implement them would be a good solution, but there are probably good reasons for this not being possible.

Anyway, any thoughts?


gman(Posted 2006) [#2]
in BMAX you can redefine a global in a subtype but the value is not respected in any methods that are not overridden (ie any methods called from the parent type use that parent types global).

i think your solution is to define an interface such that instead of using a global, it implements a method that returns a common type. then its up to the individual implementation of that interface to return whatever is needed for that specific type.

Framework BRL.Basic

Type IGadget
	Method getMyNumber:Int() Abstract ' returns and int but can be texture or whatever
	
	' the interface doesnt care how getMyNumber() is implemented, just that it returns 
	' what the interface expects
	Method whatismynumber()
		DebugLog("number is: "+getMyNumber())
	EndMethod	
EndType

Type TGadget1 Extends IGadget
	Method getMyNumber:Int()
		Return 1
	EndMethod
EndType

Type TGadget2 Extends IGadget
	Global mynumb:Int=2
	
	' individual implementations can be different as long as they match the interface
	Method getMyNumber:Int()
		Return mynumb 
	EndMethod
EndType

Local test1:IGadget=New TGadget1
Local test2:IGadget=New TGadget2

test1.whatismynumber() ' outputs 1
test2.whatismynumber() ' outputs 2



FlameDuck(Posted 2006) [#3]
I think you've just stubled over one of the central (differing) religions in OO design. One group, subscribes to the idea of strict seperation between fields (state) and methods (behavor) - this seems to more or less be the philosophy behind BlitzMAX. On the other extreme are the kind of people who believe that the objects interface is the only thing that matters, and whether you're invoking a method or accessing a field should not have a semantic difference.

Being more likely to subscribe to the former point of view, I would suggest making an abstract method named getTexture() or whatever, returning the type of field you would have wanted the field to be in, and then use a different global for each derived type, which is returned by the abstract function. The advantage is that should you in the future have a type of gadget that does need a different texture per instance (ie. a Field) you can do that too, without ruining your overall design.

Type myGadget
	Method getTexture:TPixmap() Abstract 
EndType

Type myTextGadget
	Global _texture:TPixmap
	
	Method getTexture:TPixmap()
		Return _texture
	End Method
EndType

Type myImgGadget
	Field _texture:TPixmap
	
	Method getTexture:TPixmap()
		Return _texture
	End Method
EndType	



Gabriel(Posted 2006) [#4]
That's a pretty neat solution, I like it. Thanks to both of you!


gman(Posted 2006) [#5]
glad we could help :) interfaces are a wonderful thing once you get the hang of them.


Grey Alien(Posted 2006) [#6]
Yeah the abstract GetTexture is a nice way to go.