Object Problem...

BlitzMax Forums/BlitzMax Beginners Area/Object Problem...

po(Posted 2007) [#1]
I've made an example of a problem I'm having:


It tells me 'BarList' does not exist. How do I identify the BarList of the object 'unit' properly? Shouldn't this code at least compile?


Oddball(Posted 2007) [#2]
The field Bar is an Object and Objects don't have a BarList field so it doesn't exist. You need to cast it to a TBar before you can access the BarList. See below.



po(Posted 2007) [#3]
Ah, thanks!


Paposo(Posted 2007) [#4]
Hello

Barlist is not initialized. It contains null
You need previously use write
BarList=new TList

Bye,
Paposo


Otus(Posted 2007) [#5]
Kind of relatedly, I find something weird:

This is possible:

Type Base
 Method DoSomething:Base()
 End Method
End Type

Type Derived Extends Base
 Method DoSomething:Derived()
 End Method
End Type


This is not:

Type Base
 Method DoSomething(other:Base)
 End Method
End Type

Type Derived Extends Base
 Method DoSomething(other:Derived)
 End Method
End Type


Edit: Forgot Extend


tonyg(Posted 2007) [#6]
Not sure what you're saying there Otus. They both work for me. What makes the second one 'not possible'?


Dreamora(Posted 2007) [#7]
I think he forgot the extends Base

And the reason it does not work: BM has no overloading so you can not have the same method with different types accepting than the original definition for this scope.


Koriolis(Posted 2007) [#8]
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).


Otus(Posted 2007) [#9]
Yeah, forgot extends, of course.

That's a very good explanation Koriolis, thanks.