Inheritance issue

Monkey Forums/Monkey Programming/Inheritance issue

Htbaa(Posted 2014) [#1]
I've got the following code:

Strict
	
Class FuzzyTerm Abstract
End
	
Class FzSet Extends FuzzyTerm
End
	
Class FzAND Extends FuzzyTerm
	Method New(ops:FuzzyTerm[])
	End
End
	
Function Main:Int()
	New FzAND([New FzSet, New FzSet])
	Return 0
End


Which results in an error: test.monkey<18> : Error : Unable to find overload for new(FzSet[]).

I'm porting my Fuzzy Logica module from BlitzMax to Moneky. Did it to C# a couple of weeks ago. Something like this used to be possible in BlitzMax, also in C#. Why won't Monkey accept this? FzSet is an instance of FuzzyTerm, which is what the constructor of FzAND expects...

This compiles:

FzAND([FuzzyTerm(New FzSet), FuzzyTerm(New FzSet)])


But why do I have to downcast manually? My only solution for now is this:

Class FzAND Extends FuzzyTerm
	Method New(ops:FuzzyTerm[])
	End
	Method New(ops:FzSet[])
	End
End

Why I really don't like... So manually downcasting is the only option?

Is this a limitation of the Monkey language?


Gerry Quinn(Posted 2014) [#2]
It's because what you're trying to do is not actually implicitly downcasting a FzSet. Instead you are trying to cast an array of FzSet to an array of FuzzyTerm.

FzSet is an object derived from FuzzyTerm.
FzSet[] is not an object derived from FuzzyTerm[].

The following compiles:



It is a limitation of the way arrays are handled I guess. A pet bugbear of mine is that I always think I should be able to write:
Local colour:Float[] = [ 255, 192, 192 ]

But I can't - a Float[] is a different type from an Int[]. Maybe in some cases a smarter compiler could do more, but I'm not sure how far that could safely be taken.

Anyway, maybe you will be able to find a way around the issue - I don't have time to think about it at the moment.


Htbaa(Posted 2014) [#3]
I see. Since in my case it should only accept an array with the size of 2 to 4 I guess I could make a constructor that requires 2 parameters, with 2 others optional. In theory I can accept more terms (Fuzzy IF a AND b AND c AND d AND e etc.) but that's something that rarely happens in this case.

Class FzAND Extends FuzzyTerm
	Field terms:List<FuzzyTerm> = New List<FuzzyTerm>
	Method New(op1:FuzzyTerm, op2:FuzzyTerm, op3:FuzzyTerm = Null, op4:FuzzyTerm = Null)
		Self.terms.AddLast(op1)
		Self.terms.AddLast(op2)
		If op3 <> Null Then Self.terms.AddLast(op3)
		If op4 <> Null Then Self.terms.AddLast(op4)
	End
End


Not the greatest solution in my opinion, but it works. Added benefit is that I can now do something like this:

New FzAND(foo, ba)