Additional overrides on derived classes

Monkey Forums/Monkey Programming/Additional overrides on derived classes

peterigz(Posted 2013) [#1]
Hello, in Blitzmax this worked fine but in monkey it doesn't work in this way, so what would be the alternative/correct way of doing this:

Class A Abstract
    Method Update() Abstract
End

Class B Extends A
    Method Update()
        Debuglog "I run ok"
    End
End

Class C Extends B
    Method Update()
        Debuglog "I'm not run, check with Class B :P"
    End
End


Thanks!


ziggy(Posted 2013) [#2]
This code seems good to me. what's your problem?

I've written this to check it works, and it does:
Function Main()
	Local variable:= New C
	variable.Update()
	Local variable2:= New B
	variable2.Update()
	
	variable2 = New C
	variable2.Update()
End
Class A Abstract
    Method Update() Abstract
End

Class B Extends A
    Method Update()
        DebugLog "I run ok"
    End
End

Class C Extends B
    Method Update()
        DebugLog "I'm not run, check with Class B :P"
    End
End



peterigz(Posted 2013) [#3]
Ahh, I think I've just realised what it is after looking at your code. I'm not casting appropriately before calling the update. So I'm doing:

	Method UpdateComponents()
		For Local c:tlComponent = EachIn components
			c.Update()
			If destroyed Return
		Next
	End Method


But the actual type of the component in the list is a multi-derived type so I guess it's calling the update method in tlComponent as opposed to for example tlGraphComponent that's in the list.

Thanks Ziggy I think I can solve it from there! :) I already brought this up before but looks like I forgot lol.


peterigz(Posted 2013) [#4]
Or can I... I've got lot's of different types that extend tlComponent that have their own update code, and each component is stored in a list of tlComponents, so do I really have to have lot's of If statements to check which type each is before doing the appropriate casting and calling update? I must be missing a better way of doing this... Maybe with interfaces perhaps...


ziggy(Posted 2013) [#5]
Polimorphism is designed exactly to prevent what you seem to keep wanting to do.

I mean, when you call:

myobject.MyMethod

What you're calling the MyMethod implementation of that object, whatever it is in the inheritance chain. You cannot call a parent's update method from a method instance. If you can, there's a bug on Monkey. That said, you can call a parent method from an inheriting class using the "super" keyword. But it only works from inside the class.

That's how OO inheritance works.


Jesse(Posted 2013) [#6]
as ziggy stated that is correct functionality.

here is another example:

Import mojo

Function Main()
	Local list:List<A> = New List<A>
	list.AddLast(New B)
	list.AddLast(New C)
	For Local a:A = Eachin list
		a.Update()
	Next
End
Class A Abstract
    Method Update() Abstract
End

Class B Extends A
    Method Update()
        DebugLog "I run ok"
    End
End

Class C Extends B
    Method Update()
        DebugLog "I'm not run, check with Class B :P"
    End
End


or this:

IImport mojo

Function Main()
	Local list:List<A> = New List<A>
	list.AddLast(New C)
	For Local a:A = Eachin list
		a.Update()
	Next
End
Class A Abstract
    Method Update() Abstract
    
    Method CanDo()
    	DebugLog("Did do 'A' method")
    End Method
End

Class B Extends A
    Method Update()
        DebugLog "I run ok"
    End
End

Class C Extends B
    Method Update()
    	Super.Update()
    	CanDo()
        DebugLog "I'm not run, check with Class B :P"
    End
End




muddy_shoes(Posted 2013) [#7]
I can't tell if Peter wants the parent method called or not. Post #3 suggests he does want the sub-class implementation called and has mistaken Monkey's behaviour somewhere.


ziggy(Posted 2013) [#8]
It would be great to see a complete sample of what Peter's doing to find out how to help or if he's managing to make Monkey behave weirdly on the inheritance chain somewhere


peterigz(Posted 2013) [#9]
Polymorphism, that's the word I was looking for lol. Yes I want it to call the sub class method at the bottom of the chain. Jesse's example is pretty much exactly what I'm trying. His example works fine which is great, pleased to see that it works like I'd hope it would, so now I need to figure out why my code isn't doing that as expected.

Will take a deeper look, it's very odd...


peterigz(Posted 2013) [#10]
Ok, I've found what's wrong with my code and need help finding some kind of work around or alternative way of doing it, This in a nutshell is what's going on:



Basically I'm having to make a copy of a type, but the copy is returning an "A" type even though I'm cloning a "C" type. I can't override the clone method and make it return a "C" type because it won't match the overridden method. So if any one has any ideas about how to make the above code display "I'm not run, check with Class B :P" I'd be happy :)


peterigz(Posted 2013) [#11]
I think I solved it, this works fine:



Hopefully there's no hidden surprises in there :)


Jesse(Posted 2013) [#12]
that should work! I would do it like this though:
Function Main()
	Local stuff:Container = New Container
	Local c:C = New C
	stuff.AddtoList(c.Clone())
	stuff.UpdateList()
End

Class Container
	Field list:List<A> = New List<A>
	
	Method UpdateList()
		For Local a:A = EachIn list
			a.Update()
		Next
	End
	
	Method AddtoList(a:A)
		list.AddLast(a)
	End
End

Class A Abstract
    Method Update() Abstract
    Method Clone:A() Abstract
End

Class B Extends A
	Field value:Int

    Method Update()
        DebugLog "I run ok"
    End
	
	Method Clone:A()
		Return New B		
	End Method
	
End

Class C Extends B
    Method Update()
        DebugLog "I'm not run, check with Class B :P"
    End
    
    Method Clone:A()
		Return New C		
	End Method
End



slenkar(Posted 2013) [#13]
nevermind