What Type is a Type?

BlitzMax Forums/BlitzMax Beginners Area/What Type is a Type?

Brucey(Posted 2004) [#1]
How do I ask an instance of a Type what Type it is?

Example.
I have a Vehicle Type that is extended by Bus and Car.
In a method that accepts Vehicle as a param, I would like to do different things based on the "type" of the Vehicle.. (ie. if it's a Bus do this, if it's a Car do that)

In java I would use "<var> instanceOf <type>"...

:o)
Brucey


Robert(Posted 2004) [#2]
If it is a method then declare that method abstract in the definition of the Vehicle type, and implment different methods in the Bus and Car types.


Who was John Galt?(Posted 2004) [#3]
I think you can try casting it and see if you get anything other than null back... or just have a field in the base vehicle type that indicates what vehicle it is and act appropriately on it.


Brucey(Posted 2004) [#4]
Yeah... until (?) Mark implements some kind of "isA" functionality, it looks like the easiest way will be to have an extra "type" field... unfortunately...

( I'm trying to handle resources generically (images, sounds, fonts...etc), and would like to be able to ask a particular resource what Type it is. )

The null thing is also an option, although I'm not sure what kind of overhead there is in attempting to cast things wrongly?

thanks,

:o)
Brucey


FlameDuck(Posted 2004) [#5]
The problem with using solutions like Javas instanceof is that it's not accurate, or rather may not return the result you expect (it will return true for classes that are either of Car, aswell as any classes that extend Car). If at all possible, use polymorphism (like Robert suggested) or some sort of hash based mapper instead.


Tibit(Posted 2004) [#6]
Brucey, if you have some code feel free to post it.

I guess that the problem has to do with casting, but I'm unsure. If I get it right you know how to do it in Java but not in BlitzMax? I put together a sample to show you:


Overhead in casting?
When you cast an object TypeName( TypeToCastTo ) you get 1 if success and 0 if failed, it's as simple as that. "Object" is the base-type of all types an refers to all objects. So what your trying to do, which sound like a smart way to organize your program, should work fine!

Maybe I should add this to my tutorial?


marksibly(Posted 2004) [#7]
Hi,

Yeah, casting will do it:

Function Process( vehicle:TVehicle )
  If TCar( vehicle )
    'It's a car!
  Else If TBus( vehicle )
    'It's a bus!
  EndIf
End Function


The overhead is pretty minor - in this case it will only have to check 2 superclasses (eg: bus->vehicle->object) at worse to work out if it ISA this or that.

Note that there is not currently a way to determine the 'precise' type of an object - eg: TCar( vehicle ) will return a TCar object if vehicle is of type TCar - OR any type derived from TCar.


N(Posted 2004) [#8]
Simple route:

Method ToString:String()
     Return "Vehicle"
End Method


Tada.


Brucey(Posted 2004) [#9]
Thanks for all the tips, people :-)

Looks like I'll take the casting route, as it appears to give the kind of results I would be expecting to see with something like an "isA"...

:o)
Brucey


AaronK(Posted 2004) [#10]
OK, why can't you just use polymorphism and so not have to check for type information? Unless you have a real call for it where you can't do it anyother way, I think casting should be avoided.


Bot Builder(Posted 2004) [#11]
Well, polymorphism can't do everything. In some cases you'll want completly different behaviours depending on the derived type. For instance, in FUI or BlitzUI (i think), you would pass the handle of the gadget and a message to a function and it would do something based on the type of gadget (found in a similar way as mark's method), and do something completly different in diffferent cases. Although, polymorphism would have certaintly helped, as he could have generalized functions such as move, hide, and show.


FlameDuck(Posted 2004) [#12]
For instance, in FUI or BlitzUI (i think), you would pass the handle of the gadget and a message to a function and it would do something based on the type of gadget
Look up some of the GoF Structural Patterns (like Template Method or Composite Pattern). Polymorphism is your friend.

Yes, there are cases where polymorphism won't solve your problem. This isn't one of them.


Bot Builder(Posted 2004) [#13]
True, you could call a abstracted method, but eh :)

Mark, I suppose this isnt possible with base types?

Method Poke(offset:Int,o:Object)
		If Byte(o)
			If offset>BankSize(Thebank)-1 Then
				If offset+1-AutoResizeLimit>BankSize(Thebank) then
					Throw "In the poke method of type Bank, attempted to write a byte "+(offset+1-BankSize(Thebank))+" bytes away from the limits of the bank, which is farther than the allowed distance of "+AutoResizeLimit+", for auto resizing.  This implies somethings gone wrong and you may be using a value in the incorrect parameter."
				Else
					ResizeBank(Thebank,offset+1)
				Endif
			EndIf
			PokeByte(Thebank,offset,Byte o)
		ElseIf Short(o)
			PokeShort(Thebank,offset,Short o)
		ElseIf Int(o)
			PokeInt(Thebank,offset,Int o)
		ElseIf Long(o)
			PokeLong(Thebank,offset,Long o)
		ElseIf Float(o)
			PokeFloat(Thebank,offset,Float o)
		ElseIf Double(o)
			PokeDouble(Thebank,offset,Double o)
		Endif
	EndMethod


:( can't convert object to byte. this is one situation in which neither polymorphism or mark's method can help me. Guess I'll just have to make a bunch of them.

BTW, Blitzmax needs overriding of functions and methods!


FlameDuck(Posted 2004) [#14]
:( can't convert object to byte. this is one situation in which neither polymorphism or mark's method can help me.
True.

BTW, Blitzmax needs overriding of functions and methods!
Overloading, surely?