What Type is a Type?

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

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

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.

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.

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

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.

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:
Type Vehicle
	Global Creator$ = " FX-Factory"
	Field Broken=False	
	
	Method Test()
		If Not Broken Print "Vehicle works!" Else Print "It's broken!"
	End Method

	'Self refers to the Type calling
	'Example:
	'Bus.Collide(Helicopter) 
	'Bus is refered to as Self and Helicopter as V
	Method Collide(V:Vehicle)
		If Car(Self) And Car(V) Print "Car Collide with Car"
		If Car(Self) And Bus(V) Print "Car Collide with Bus"
		If Bus(Self) And Car(V) Print "Bus Collide with Car"		
		If Bus(Self) And Bus(V) Print "Bus Collide with Bus"
		Broken=True'Note that Self. is not needed here
		V.Broken=True
	EndMethod
	
End Type

Type Car Extends Vehicle
	Method Test()
		If Not Broken Print "Car works!" Else Print "Car is broken!"
	End Method	
End Type

Type Bus Extends Vehicle
	Method Test()
		If Not Broken Print "Bus works!" Else Print "Car is broken!"
	End Method
End Type

C:Car = New Car
B:Bus = New Bus

B.Collide(C)

Car2:Car = New Car
Bus2:Bus = New Bus

Bus2.Collide(B)
Car2.Collide(Bus2)
Car2.Collide(C)

Car2.Test
C.Test
B.Test
Bus2.Test



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?

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.

Simple route:

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


Tada.

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

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.

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.

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.

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!

:( 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?