使用 'Class' 数据类型时,如何指定类型以便我只接受特定 class 的子 class?

When using the 'Class' datatype, how can I specify the type so I only accept subclass of a specific class?

我有一个方法接受 Class 类型的参数,我只想接受扩展 SuperClass 的 classes。现在,我能想到的就是这个,它对实例进行 运行 次检查:

public function careless(SomeClass:Class):void {
    var instance:SomeClass = new SomeClass();
    if (instance as SuperClass) {
        // great, i guess
    } else {
        // damn, wish i'd have known this at compile time
    }

}

有没有办法做这样的事情,所以我可以放心 Class 实例扩展了一些超级 class?

public function careful(SomeClass:[Class extends SuperClass]):void {
    var instance:SuperClass = new SomeClass();
    // all is good
}

您不能在 ActionScript 3 中执行此操作。在 C# 等语言中,您可以执行以下操作(如果语法不正确,请原谅我):

public void Careless<T>() where T : SuperClass

但是AS3没有'generics'。不幸的是,我知道如何做你想做的事情的唯一方法就是你已经做过的事情。

可能更适合您的用例的模式可能类似于:

class SuperClass
{
    public static function careless():void
    {
       var instance:SuperClass = new SuperClass();

       // ...
    }
}

在 ActionScript 3 中进行静态类型检查的唯一方法是提供 实例 class.

这是可能的,但它很昂贵。您可以在 Class(不是实例)上使用:

flash.utils.describeType

然后你会得到一个 XML,其中包含一堆信息,包括 class 的继承。就像我说的那样,这是一个昂贵的过程,可能创建一个实例并检查它在大多数情况下会更快。

如果您无论如何都要实例化它,为什么不接受一个允许您将其键入 :SuperClass 的对象呢?

careless(SomeClass);
//vs.
careless(new SomeClass);

就您的代码而言,问题不大。 不过还是有一些不同:

  • 必须创建对象,因为需要一个对象。如果您的函数在某些情况下没有实例化 class,这可能是个问题。传递对象或 null 的附加逻辑会使函数调用膨胀。
  • 如果你不能在该函数外调用构造函数,它就不会 要么工作。

工厂模式都解决了。传递一个工厂作为生产 SuperClass 个对象的参数。

function careful(factory:SuperClassFactory)

您的要求:

I want to only accept classes that extend SuperClass

I need to pass in a Class so that it can be instantiated many times by other objects later

可以通过传入您需要的 class 实例并使用 Object.constructor() 方法来满足。

public function careful(someInstance:SuperClass):void {
    //you probably want to store classRef in a member variable
    var classRef: Class = someInstance.constructor();

    //the following is guaranteed to cast correctly,
    //since someInstance will always be a descendant of SuperClass  
    var myInst:SuperClass = new classRef() as SuperClass; 
}

More reading here.