How to cast to an extended type and access field?
BlitzMax Forums/BlitzMax Programming/How to cast to an extended type and access field?
| ||
I can't seem to figure out how to access the field "Vertices" after extending the type.... how is this supposed to work?Type Shape Field Format:Int=0 End Type Type ShapeFloat Extends Shape Field Vertices:Float Ptr=Null End Type Type ShapeDouble Extends Shape Field Vertices:Double Ptr=Null End Type Local ShapeToUse:Shape=New Shape ShapeToUse.Format=0 If ShapeToUse.Format=0 Then ShapeToUse=ShapeFloat(ShapeToUse) Else ShapeToUse=ShapeDouble(ShapeToUse) ShapeToUse.Vertices=Null It says the `Vertices` field is not defined? |
| ||
Umm.. ShapeToUse should be Null, given your code. |
| ||
You can only access fields present in the -declared type- of the object. So things like this really have no effect, ShapeToUse=ShapeFloat(ShapeToUse) since the type of ShapeToUse is always just Shape. You'd need to declare a new variable of type ShapeFloat or ShapeDouble to be able to access the Vertices field. |
| ||
That behavior is a weak point of Blitzmaxs polymorphism (dontīt know if other languages are diferent in that regard). It force you to add fields and methods to the super class, even if they are used only in some of the extended classes. But this is only needed for the fields and methods which are called from the outside of the class. |
| ||
That behavior is a weak point of Blitzmaxs polymorphism (dontīt know if other languages are diferent in that regard). No, this is exactly how it should be... It force you to add fields and methods to the super class, even if they are used only in some of the extended classes. No, it doesn't. Consider this, both subclasses have a vertices field, so both should have a SetVertices method. This should be a pure-virtual method in the base class and be implemented by the subclasses.If anything, the above is just plain bad design. |
| ||
Make GetVertices an abstract method of shape, which always (has to) return a double, but then at least you could have vertices as either a float or double in your extended types. |
| ||
Thanks for the feedback guys! It looks like I'll have to rewrite some code, then, to either add FloatShape and DoubleShape references as new fields in Shape, or just in-line it to one bloated Shape object containing some potentially unused fields. I appreciate what Nilium is saying about proper use of OO design principles, ie I should really have Get and Set methods to access the fields rather than directly accessing them. And that probably would be strictly `correct` in terms of OOp'ness. But to me these methods are inefficient. I know it could potentially make later changes easier, not having to re-write lots of references to changed fields, but since I don't think it likely that these fields will change I don't see a need for me to use it. I take some issue with trying to make it easier for me to write and modify the code, because it has the side effect of making the compiled program slower to execute. Also I prefer to directly access fields from anywhere in my code, directly. Yes it's a bit old-school procedural-design etc but that's my choice for now. |
| ||
the biggest problem there is that you just can't swap variables. you have to create instances of each. if the instance you created(such in the base)don't contain the variable then you wont be able to use it. I don't know exactly what your goal is but you can try something like this:Type TPoly Field Format:Int=0 Field shape:Tshape Method Load(s:Tshape) shape = s End Method Method clear() shape.clear() End Method End Type Type Tshape Abstract Method clear() Abstract End Type Type ShapeFloat Extends TShape Field Vertices:Float Ptr Method clear() vertices = Null End Method End Type Type ShapeDouble Extends TShape Field Vertices:Double Ptr Method clear() vertices =Null End Method End Type Local ShapeToUse:Tpoly=New Tpoly ShapeToUse.Format=0 If ShapeToUse.Format=0 Then ShapeToUse.Load(New ShapeFloat) Else ShapeToUse.Load(New ShapeDouble) shapeToUse.clear() [edited] and this is not slower than having to add a couple of "If" statements. which you would have to use if you do it your way. |
| ||
Thanks for the effort Jesse. I am probably going to just add:Field ShapeF:FloatShape Field ShapeD:DoubleShape to my Shape object. Each of them contain several fields of either float or double format and this looks like it'll be fairly sensible. |
| ||
I am probably going to just add ... to my Shape object Right. Better to stuff everything into one Type than build a design using polymorphism :-) |
| ||
? Are you being sarcastic? |
| ||
I hope so :-p |
| ||
Are you being sarcastic? It seems that he is. I find it surprising that people haven't caught a hold on Brucey's character yet. |
| ||
I find it surprising that people haven't caught a hold on Brucey's character yet Probably because he's pretty much character-less... ... although I think I'm still missing something, as I often get a lairy eye going through customs. Pah! |
| ||
I think you are correct. As opposed to being arrogant. Oh Well. |