PDA

View Full Version : "Uptyping" of inherited attributes.


spoxta
08-09-2007, 04:45 PM
Hi,

I am not sure if this is in line with any OO programming principles,
but I came across a need, so I wanted to check if this is possible
and/or receive any recommendations how to approach this.

Here is the situation.

I have base classes

BaseCalculate and
BaseData

and I have various derived classes from both, like:

FooCalculate and
FooData

BarCalculate, BarData

BazCalculate, BazData

all the common methods and attributes of the implemented algorithms
are bundled in the Base classes.

Each Calculate class has attributes to hold objects of its
corresponding Data counterpart. In the BaseCalculate class there are
methods that actually do some work on these data objects (but only
interface with what is provided by the BaseData class).

The actual calculation algorithms use typically additional methods
from the derived Data classes.

Right now, to implement this I declared a protected variable in BaseCalculate like:

protected var _mydata:BaseData;

But in (e.g.) FooCalculate, this variable is not assigned a BaseData object,
but a FooData object, like:

_mydata = new FooData;

so far so good, all ok, since FooData is derived from BaseData is can
be assigned.

Now the ugly part is, that whenever I need to call specific methods from
FooData, BarData or BazData which are not in BaseData I have to
explicitly tell that the object in _mydata is not only of type BaseData but
actuall FooData, meaning I write a lot of code like this:

(_mydata as FooData).fooDataSpecificFunction();

What I would like instead is a way to tell the FooCalculate class that the
inherited _mydata attribute is actually of type FooData, so that I do not
need to do it everywhere in the code individually.

Any ideas how to do this??

My naive approach would have been to override the declaration of _mydata
with the more specific type, but of course this does not work, but maybe
there is a way to achieve it anyway.

I also tried to declare _mydata private and redeclare it in derived
class with the specific type, but this leads to having two separate
references with the one in BaseCalculate uninitialised....

Hmmm now thinking of it, I could write a protected setter in BaseCalculate
and when the specific object is created it will be set in both variables
(which remain private). That could work....

dr_zeus
08-10-2007, 06:21 PM
You're shouldn't change anything. Cast it as FooData or whatever subclass of BaseData that you need to use. The reason this is the right way is because the compiler can optimize your code much easier when you strongly-type your variables (and casting helps to keep things strongly typed). When people say that ActionScript 3 runs 10-30 times faster than AS2, strong typing is the reason.

If you need to do multiple operations on the data at once, cast it and put it in a local variable. You'll only need to cast once in that method, and you'll have the strong typing.

var myFooData:FooData = this._myData as FooData;
myFooData.fooDataSpecificFunction();
myFooData.fooDataSpecificFunction2();

spoxta
08-10-2007, 07:12 PM
Thanks, it basically confirms my idea at the end of my posting.
Since the multiple operations are spread out in the subclass I just use
a specific type (private) attribute in the derived class rather than a local
variable.

So I have in:

BaseCalculate {
...
private var _myData:BaseData;

...
protected function set myData(md:BaseData):void {
_myData = md;
}
...
}


and in:


FooCalculate {
...
private var _myData:FooData; // more specific type
...
public function FooCalculate():void {
...
_myData = new FooData();
super.myData = _myData; // sets the reference in the base class
}
...
}


Works exactly as I wanted it do and uses the strongest type wherever possible.