v77a - Parent class method not seen by interface

Monkey Forums/Monkey Bug Reports/v77a - Parent class method not seen by interface

itto(Posted 2014) [#1]
When creating an instance of an extended class and storing it in a variable with the class' implemented interface as type, the parent class method the interface expects is not seen and the compiler fails with error "Method IFoo.GetName:String() must be implemented by class Bar".

Discussion

Code:

Interface IFoo
	Method GetName:String()
End

Interface IBar Extends IFoo
	Method SetName(name:String)
End

Class Foo Implements IFoo
	
	Method GetName:String()
		Return name
	End
	
	Private Field name:String = "John Doe"
	
End

Class Bar Extends Foo Implements IBar

              ' without implementing this, the code doesn't work,
              ' but GetName is already implemented by the parent class Foo!

	' Method GetName:String()
	' 	Return name
	' End

	Method SetName(name:String)
		Self.name = name
	End

End

Function Main()

	Local foo:IBar = New Bar()

	foo.SetName("Mister X")
	Print foo.GetName()
	
End



MikeHart(Posted 2014) [#2]
This works...

Function Main()

	Local foo:Bar = New Bar()

	foo.SetName("Mister X")
	Print foo.GetName()
	
End



itto(Posted 2014) [#3]
It works cause you declared foo:Bar instead of foo:IBar. The point of my code is that I want to work with interfaces, not concrete classes. My code works if you uncomment the commented GetName method, but that defeat the purpose of class inheritance entirely.


Gerry Quinn(Posted 2014) [#4]
It works if you cast foo to a Bar:

Print Bar( foo ).GetName()

However, you still get an error if you cast it to an IFoo.


itto(Posted 2014) [#5]
Casting it to an IFoo defeats the purpose of interface inheritance. If I cast it to an IFoo I won't be able to access methods available only to the IBar interface.

IBar inherites from IFoo so it should have the GetName method. In fact, it has it since the compiler error states "Method IFoo.GetName:String() must be implemented by class Bar", so the compiler recognizes the GetName method from the interfaces, it just doesn't understand that Bar has the method declared already since it inherits it from Foo.


marksibly(Posted 2014) [#6]
I'll have a closer look at this eventually, but for now you'll have to work it around, eg: via a GetName method in Bar that returns Super.GetName().

The problem is that C#/Java/C++ all have their weird little limitations and idiosyncrasies when it comes to interfaces, and in this case it's C++ that's not playing nice (it's usually C#), and turning off the check that's causing the error results in an error from the C++ compiler.

Not sure if there's a 'fix' for this in c++. Alternatively, Monkey could 'insert' calls to super class methods where appropriate etc, but that's a relatively big job that I wont be taking on in the near future.


muddy_shoes(Posted 2014) [#7]
Deja vu: http://www.monkeycoder.co.nz/Community/posts.php?topic=3105


itto(Posted 2014) [#8]
Thank you mark and all you guys for support. I see this bug has been already reported in mid 2012 by muddy_shoes and hasn't been fixed yet.
This thing is really a pain in the a** because it prevents people to think and design with good oop principles using interfaces.
I'm using a Super.MethodName() workaround for now, but really a broken design feature not fixed after two years, seriously? :/
Since the problem is just one picky language and it can easily be solved by automatically inserting a method with a call to the parent's method, it shouldn't be that painful to fix.
By the way this is the best fun I had programming a game since the days of blitzbasic, game development is unbelievably fast now! :)


Gerry Quinn(Posted 2014) [#9]
"Casting it to an IFoo defeats the purpose of interface inheritance". You're right - I didn't read the code properly. I thought it was just Bar that implemented the two interfaces, rather than IBar extending IFoo.