Reputation: 604
Possibly bad practice but I'm not well versed in software design anyway (I'm sure this question would have been asked before but I can't seem to find the right terminology)...Anyhow, it's just another curiosity of mine I'd like to have answered.
So I have worked in a way where I type a base class variable to type Object or Sprite or something similar so that in my subclasses, I can instantiate my custom classes into them and store it. And when I access it, I just cast that variable to ensure I can access the methods.
Take this example, so that you know what I'm talking about:
public class BaseClass
{
protected var the_holder_var:Object;
public function BaseClass()
{
//Whatever abstract implementation here...
}
}
Now, my subclasses of that base class usually use an interface but for simplicity sake, I'll just write it without it.
public class AnExtendedClass extends BaseClass
{
public function AnExtendedClass()
{
//Instantiate my own class into the base class variable
this.the_holder_var = new ACustomClassOfMine();
//Then I can use the 'hackish' getter function below to
//access the var's functions.
this.holder_var.somefunction()
}
private function get holder_var():ACustomClassOfMine
{
return this.the_holder_var as ACustomClassOfMine;
}
}
This works and I'm sure it will make some ppl cringe (I sometimes cringe at it too). So now, my question, is there a way to recast/retype that base var in my extended subclass?
kinda like this:
public class ExtendedClass extends BaseClass
{
//Not possible I know, but as a reference to see what I'm asking about
//Just want to change the type....
override protected var the_holder_var:ACustomClassOfMine;
public function ExtendedClass()
{
//Then I can forget about having that hackish getter method.
this.the_holder_var = new ACustomClassOfMine();
this.the_holder_var.somefunction();
}
}
I was thinking of typing most of my base class vars that I use as holders as type * and retyping them as I extend the class. (I could use it here too but yeah...) Thoughts? Comments? Ideas?
Upvotes: 1
Views: 1208
Reputation: 11319
I actually think your code (apart from the hypothetical addition at the end) is pretty alright. The practise of adding accessors to solve the type issue you're dealing with is a solid one. I would advise to rename the accessor to show it is a cast, maybe get holderVarAsCustom():ACustomClassOfMine
(I'm also not a big fan of the underscores, that's another language's convention), but that's personal preference. What I'd do to solve your last problem is just create a matching setter function:
private function set holderVarAsCustom(value:ACustomClassOfMine):void {
this.the_holder_var = value;
}
This way you can access the correctly typed holder var for both read and write operations with complete type safety:
holderVarAsCustom = new ACustomClassOfMine();
holderVarAsCustom.someFunction();
I would definately advise against dropping the type safety by including arrays and what not, that just makes it unstable.
Upvotes: 1
Reputation: 2367
I would not try to tinker this behaviour, since you can't change the declared type of a variable once declared, no matter how hard you try. What I do in such cases, I either cast the variable if I use it sparingly or the object it references may change, or I add another variable with the type I want and let the other variable point to the new one. Like this:
public class A {
protected var object:Object;
public function A() {
//Whatever abstract implementation here...
}
}
and
public class B extends A {
protected var other:MyClass;
public function B() {
super();
this.other = new MyClass();
this.object = this.other;
}
}
Having it this way, class A uses the object via the this.object
reference, and class B can use the this.other
or both. But both references point to the same object. The only issues with this are:
Upvotes: 0
Reputation: 333
I must admit that i'm a little confused as to why you want to do this, but here goes. Could you not utilise the fact that Array's can hold different data types. So something like this:
public class BaseClass
{
protected var customStorage:Array;
public function BaseClass()
{
//Whatever abstract implementation here...
}
}
You could then access it with an associative method and a property:
public class AnExtendedClass extends BaseClass
{
private static const myName:String = "myName";
public function AnExtendedClass()
{
//Instantiate my own class into the base class variable
customStorage[myName] = new ACustomClassOfMine();
objectIWant.somefunction()
}
private function get objectIWant():ACustomClassOfMine
{
return ACustomClassOfMine(customStorage[myName]);
}
}
Is that any better?
Upvotes: 0