OOP and Inheritance without Casting

Monkey Forums/Monkey Programming/OOP and Inheritance without Casting

AdamRedwoods(Posted 2012) [#1]
quick question

pseudo-code
[monkeycode]
Class TEntity
Method CopyEntity:TEntity() Abstract
End

Class TMesh Extends TEntity
Method CopyEntity:TEntity()
Local m:TMesh = New TMesh
return m
End
End
[/monkeycode]

Now if i use CopyEntity(), I currently have to cast, otherwise it's a TEntity != TMesh compiler error.
Ideally, I want to NOT use casting() or <Parameters>.
[monkeycode]

Local myMesh:TMesh = TMesh(oldmesh.CopyEntity())
[/monkeycode]

How to do this? I can't seem to think of a clean, simple way for generic programming or interfaces to do this. I believe this is a contravariance problem, if I'm using the terminology correctly.


AdamRedwoods(Posted 2012) [#2]
Wow, I'm an idiot, I've already asked this:
http://monkeycoder.co.nz/Community/posts.php?topic=3030


...but I still wonder if there's a better way? Generic Interfaces?


Rone(Posted 2012) [#3]
Hi,
I tried the same a few days ago, normally I whould do this:
Class Entity< T >
	Method Copy:T() abstract 
End 

Class Mesh extends Entity < Mesh >
	Method Copy:Mesh()
		Return null
	End 
End

Class Camera extends Entity < Camera >
	Method Copy:Camera()
		Return null
	End 
End

But the monkey compiler says: "Cyclic declaration of Mesh"... Do not get it, because the generated code would be valid...maybe a bug?


skid(Posted 2012) [#4]
Simplest method I can think of is to have Copy provide the standard interface and implement Clone for each specific type. The Entity interface could also be a Class in the following:

Interface Entity
	Method Copy:Entity()		
End 

Class Mesh Implements Entity
	Method Clone:Mesh()
		Return Null
	End

	Method Copy:Entity()		
		Return Clone()
	End
End


For Entity style clones arguments for Recurse (copy all children) and Deep (for Mesh make a copy of the vertex and triangle buffers also) make the need of a non specific CopyEntity style function seem a little non obvious.


dmaz(Posted 2012) [#5]
[rant]Sorry, but I think this should just work, it did in bmx(and I know this is not bmx). One shouldn't have to jump through these hoops for something so simple and clear.


AdamRedwoods(Posted 2012) [#6]
Skid, your method still would give an error since it's returning TEntity, which is a supertype (not a subtype) of TMesh.
Local mesh:TMesh = entity.Copy()


I think it should *just work*.

Here's a link to the C++ situation:
http://www.lwithers.me.uk/articles/covariant.html
And the Java explanation, which was allowed in J2SE 5.0:
http://www.java-tips.org/java-se-tips/java.lang/covariant-return-types.html


So my thought is that Monkey *should* allow a return subtype of the extended return type. It fulfills the contract as a supertype fits the definition of the subtype (but not the other way around).

But i see this is not allowed in AS3...
http://stackoverflow.com/questions/9853757/flex-override-to-change-return-type


peterigz(Posted 2012) [#7]
Just ran into this problem. Thankfully Skids method works OK for me, I haven't used an interface though, but still seems to work.