AS3 - 在子类中永久地重新键入/转换一个继承的变量?

时间:2011-06-24 03:32:48

标签: actionscript-3

可能是不好的练习但是我对软件设计并不熟悉(我确定之前会问过这个问题,但我似乎找不到合适的术语)......无论如何,这只是另一个好奇心我想回答。

所以我的工作方式是键入一个基类变量来键入Object或Sprite或类似的东西,以便在我的子类中,我可以将自定义类实例化到它们中并存储它。当我访问它时,我只是转换该变量以确保我可以访问这些方法。

以此为例,以便您知道我在说什么:

public class BaseClass
{
  protected var the_holder_var:Object;

  public function BaseClass()
  {
    //Whatever abstract implementation here...
  }
}

现在,我的基类的子类通常使用一个接口,但为了简单起见,我只是在没有它的情况下编写它。

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;
  }
}

这很有效,我相信它会让一些人感到畏缩(我有时会畏缩不前)。 所以现在,我的问题是,有没有办法在我的扩展子类中重新/重新键入base var?

有点像这样:

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();
  }
}

我正在考虑键入我用作类型*的持有者的大多数基类变量,并在扩展类时重新输入它们。 (我也可以在这里使用它但是......) 思考?评论?想法?

3 个答案:

答案 0 :(得分:1)

我实际上认为你的代码(除了最后的假设添加)是非常好的。添加访问器来解决您正在处理的类型问题的做法是一个坚实的做法。我建议重命名访问者以显示它是演员,也许是get holderVarAsCustom():ACustomClassOfMine(我也不是下划线的忠实粉丝,这是另一种语言的惯例),但这是个人偏好。我要解决你的最后一个问题就是创建一个匹配的setter函数:

private function set holderVarAsCustom(value:ACustomClassOfMine):void {
  this.the_holder_var = value;
}

通过这种方式,您可以访问正确类型的holder var,以进行读取和写入操作,并具有完整的类型安全性:

holderVarAsCustom = new ACustomClassOfMine();
holderVarAsCustom.someFunction();

我肯定会建议不要通过包含数组来降低类型安全性,而不是这样,这只会让它变得不稳定。

答案 1 :(得分:0)

我必须承认,我为什么要这样做有点困惑,但是这里有。你能不能利用Array可以容纳不同数据类型的事实。所以像这样:

public class BaseClass
{
      protected var customStorage:Array;

      public function BaseClass()
      {
        //Whatever abstract implementation here...
      }
}

然后,您可以使用关联方法和属性访问它:

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]);
   }
}

这样更好吗?

答案 2 :(得分:0)

我不会尝试修改这种行为,因为无论你怎么努力,你都无法在声明后更改变量的声明类型。 在这种情况下我做的是,如果我谨慎地使用它或者它引用的对象可能会改变,或者我添加另一个具有我想要的类型的变量,并让另一个变量指向新变量,我要么转换变量。像这样:

public class A {

    protected var object:Object;

    public function A() {
        //Whatever abstract implementation here...
    }

}

public class B extends A {

    protected var other:MyClass;

    public function B() {
        super();
        this.other = new MyClass();
        this.object = this.other;
    }

}

通过这种方式,A类通过this.object引用使用对象,B类可以使用this.other或两者。但两个引用都指向同一个对象。唯一的问题是:

  • 在同一个类中对同一个对象有两个引用是丑陋的(无类型变量和强制转换)
  • 如果其中一个对象可能指向可以在运行时更改,则必须非常小心地同步这些更改