Expected Behaivor or bug (Stack with OOP-classes)?
Monkey Forums/Monkey Programming/Expected Behaivor or bug (Stack with OOP-classes)?
| ||
Dear monkeyX-users, I getting more and more used to utilize the option that Stacks or Lists can have different classes as long as they are based on the same BaseClass. But today I stumbled over an issue whereas I'm not sure if this is indended / bug or something on my end: Example (my classes are a bit more complex): Class Point Field x:Int Field y:Int End Class BouncingPoint extends Point Field bounce:Bool End Class Test Field testStack:Stack<Point> = New Stack<Point> Method AddPoint:Void(point:Point) Stack.Push(point) End End Now, if I want to access for example the 4 element of the stack which may was an BouncingPoint and retrieve the bounce-value, I can't!?! if testStack.Get(3).bounce bla,bla The compiler (for desktop at least) gives the following error: Error:Identifier 'bounce' not found Any ideas? I mean, I could go around and assign the element to local var, but would that be efficient? Thx in advance |
| ||
The stack is storing and returning Point references. The Point class doesn't have a bounce field. You need to cast the reference or change the Stack declaration to use BouncingPoint. |
| ||
maybe you mean this Field testStack:Stack<BouncingPoint > = New Stack<BouncingPoint > Stack.Push(point) ??? testStack.Push(point) |
| ||
Example on how to solve it:local bpoint:BouncingPoint 'This will try to convert the result of testStack.Get(3) to a BouncingPoint instance. If it fails, it will return null: bpoint = BouncingPoint( testStack.Get(3) ) 'Then we can do whatever with our bpoint variable, after checking it's not null: if bpoint <> null then bpoint.bounce blah blah Just a small sample which I hope makes things a nit easier to understand. |
| ||
@ziggy I see that differently. |
| ||
another, more complex, way: |
| ||
Dear all, as the OP I want to come back to this topic. The example I gave in the first post was only a very simple version what I'm doing with my entity and GUI system. The GUI system has a baseClass and several (unlimited) number of extended classes in itself. During the update or render method it cycles through all the attached classes (collected in a stack) as the basic drawing routines are sometimes the same - sometimes are different. Using an overwriting method works very well. During some further thinking today I came to the similar conclusion as Adam with the difference that I implemented a method (instead of an interface) in the baseClass to change the value which returns a False (as there is no variable to be changed) and in the extended class an overwriting method which returns true, Similar it would be returning Null if there is no value to grab and the value if it exists. Its not to simple - but at least a solution. But it still doesn't answer my question - as far as I understand I have a reference to the bouncingPoint in the stack. Why can't I access the value directly? BR Wyl |
| ||
as far as I understand I have a reference to the bouncingPoint in the stack. Why can't I access the value directly? muddy_shoes answer: The stack is storing and returning Point references. The Point class doesn't have a bounce field. You need to cast the reference or change the Stack declaration to use BouncingPoint. ...or another explanation: BouncingPoint is a Point Point is NOT a BouncingPoint (as BouncingPoint contains more information than Point) Stack.Get(3) is a Point, but also a reference to a BouncingPoint. In order to tell the compiler it's a BouncingPoint, it must be dynamically casted. |
| ||
i believe Class BouncingPoint extends Point means the BouncingPoint include Point struct |
| ||
Yes, that is what is happening 'under the hood'. A Point object stores an x and a y, while a BouncingPoint object stores x, y and bounce. And there could be other extended point types that store other things, or have overridden methods etc. The thing is, even if you know all the points you will be using are BouncingPoints, the compiler isn't clever enough to figure that out by itself, so you have to tell it - either by explicitly making a stack of BouncingPoints (but then you cannot legally put ordinary Points on it), or by casting an object from a Point stack to a BouncingPoint. There are various ways and means of organising things like this - there is no one perfect way, and what is best depends on the situation. |
| ||
please apologize if I bring this topic again on top, but this time I only want say thank you to all of you who helped me to understanding some of the pieces under the hood :-) |