Basic Inheritance/Polymorphism question

Monkey Forums/Monkey Programming/Basic Inheritance/Polymorphism question

MarkSponge(Posted 2011) [#1]
Could anyone explain to me why this doesn't work please?

Maybe I'm missing something really obvious.....

Import mojo

Class BaseClass 
	Field baseOne:String = "base"
End

Class ChildClass Extends BaseClass
	Field childOne:String = "child"
End

Class Test Extends App

    Method OnCreate:Void()
		Local b1:BaseClass = new ChildClass
		b1.childOne = "this doesnt work" '<---- Error : Identifier 'childOne' not found.
		ChildClass(b1).childOne = "this doesnt work either" '<---- Error : Identifier 'childOne' not found.
    End
End

Function Main:Void()
       New Test
End



Hima(Posted 2011) [#2]
b1.childOne = "this doesnt work"

This one doesn't work because you're trying to access childOne from BaseClass pointer.

ChildClass(b1).childOne = "this doesnt work either" '<---- Error : Identifier 'childOne' not found.

This one doesn't work in monkey. I don't know why. But you have to do it like this

Local child:ChildClass = ChildClass(b1)
child.childOne = "this should work"



MarkSponge(Posted 2011) [#3]
Thanks, that does work.... but it does feel dirty...

Could the casting error be a bug? Can anyone confirm?


Jesse(Posted 2011) [#4]
it is not a bug. when you declared the class, you declared it as BaseClass not as ChildClas. BaseClass doesn't know anything about the ChildClass so there fore it doesn't know what you mean when you try to acces its child properties.
if you declare the object as a childclass the childClass inherits all of the qualitites of the baseclass through the "extends" and therefore you are able to access fields from the parent class. the reason you cast it as mentioned by Hima is becasue you can assign the childclass to a BaseClass variable
like so:
mybase:BaseClass = new ChildClass

this way you can store all of your extended types as base class. while it's stored as a baseclass you can not access any of the childclass properties unless you cast it to childClass:
childclass(mybase).childone = "this works"

you can access method and functions in a child class that has been declared as a base class only if you declared prototypes of functions in the parent type. example:
code]
Import mojo

Class BaseClass 
	Field baseOne:String = "base"


      method assign(s:string)abstract
      method update() abstract
      method display() abstract
End

Class ChildClass Extends BaseClass
	Field childOne:String = "child"

      method assign(s:string)
            childOne = s
      End Method

       method display()
           print childOne
       end method

      method update()
     end method

End

Class Test Extends App

    Method OnCreate:Void()
		Local b1:BaseClass = new ChildClass
		b1.assig("this works") 
                b1.display()
    End
End

Function Main:Void()
       New Test
End



the above code renders the baseclass useless by itself. meaning you can not create a type of "baseClass" such as:
local a class:baseClass = new BaseClass '<this will give an error


that is the basic principle of polymorphism and is the way it supposed to work.


MarkSponge(Posted 2011) [#5]
childclass(mybase).childone = "this works"

Have you actually tried that without an abstract class? It doesn't work and I may yet need to instantiate a BaseClass object.

I did manage to figure out a tidier solution. Putting brackets around the whole statement works. Like:
Local b1:BaseClass = new ChildClass
(ChildClass(b1)).childOne = "works :D" ' <-- notice the () around the ChildClass(b1)



Jesse(Posted 2011) [#6]
yes that's what Hema stated and is perfectly valid. the reason you can do that is because you can pass it to a function as base or as child

example:
Local b1:BaseClass = new ChildClass
assign(b1)

function assign(obj:ChildClass)
    obj.childOne = "works :D"
End



Hima(Posted 2011) [#7]
@MarkSponge
So simple that I couldn't believe why I didn't try that before separating it like I told you. Thanks!


MarkSponge(Posted 2011) [#8]
I think you misunderstand me.
Local b1:BaseClass = new ChildClass
b1.childOne = "this doesnt work" '<---- Error : Identifier 'childOne' not found.
ChildClass(b1).childOne = "this doesnt work either" '<---- Error : Identifier 'childOne' not found.

The last line *should* work in principal. My problem was that it gave a compilation error because the cast to ChildClass wasn't being picked up. To fix that I had to wrap it in another set of brackets. I have no problem with the principles of polymorphism, it was the syntax that was tripping me up.

But anyway, it's sorted now. Thanks for your help.


Jesse(Posted 2011) [#9]
no I understood it perfectly. The problem is that baseClass does not know what childOne is therefore you get the compiler error even if it comes from a childClass. As long as the childClass is in a BaseClass you will get an error unless you cast it back to it's original class.

my fault, I did misunderstood.
you are right It is a bug.