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