Yes but you didn't explain why it works for the return type.
It is good, and safe that it works for the return type : it's called covariance.
By example it allows to oevverride a "Clone" method that whose return type is always the right one (the same as the type of its containing type).
That is, you can do
Type Base
Method Clone:Base()
Local obj:Base = New Base
' here, copy fields
Return obj
End Method
End Type
Type Derived Extends Base
Method Clone:Derived() ' Return type is 'Derived' even though you override the method in Base, whose return type is 'Base'
Local obj:Derived = New Derived
' here, copy fields
Return obj
End Method
End Type
Beyond being usefull, allowing this is also safe as in every possible case the real type of the return value for Clone is a derived type (or exactly the type) expected by the compiler. And is thus trivially convertible to the expected type. This wouldn't hold true for parameters.
If modifying the type of parameters in an overriding method was allowed, you would subvert the type system, and would have nice little crashes.
Type Base
Method DoSomething(other:Base)
End Method
End Type
Type Derived Extends Base
Method DoSomething(other:Derived)
End Method
End Type
Local objBase:Base = New Base
Local objDerived:Base = New Derived ' 'Derived' type instance, but reference decalred as 'Base'
objDerived.DoSomething(objBase)
Let's say the compiler accepts the overriding in 'Derived'
Then at the last line, the call to DoSomething would lead to calling Derived.DoSomething (not Base.DoSometing) as expeected. The compiler wouldn't complain on that line, because at compile time the compiler sees objDerived as a reference to an instance of 'Base' (not 'Derived'). So it will check the call agains Base.DoSomething, and say "mm ok, it expects an instance of 'Base' as a parameter, that's waht I'm given so it's fine". Excepts that at runtime it's not Base.DoSomething that gets called, it's Derived.DoSomething.
Thus Derived.DoSomething will work on 'other' just as if it was an instance of 'Derived', but ti's not. It's an instance of 'Base'. You'd better not try to access a field only declared in 'Derived' and not in 'Base'...
It's a classical problem when mixing two different concpets: static type (as known by the compiler) and dynamic type (the effective type of an object at runtime).