使用“类”数据类型时,如何指定类型以便只接受特定类的子类?
Posted
技术标签:
【中文标题】使用“类”数据类型时,如何指定类型以便只接受特定类的子类?【英文标题】:When using the 'Class' datatype, how can I specify the type so I only accept subclass of a specific class? 【发布时间】:2015-03-28 03:04:31 【问题描述】:我有一个接受Class
类型参数的方法,我只想接受扩展SuperClass
的类。现在,我能想到的就是这个,它对实例进行运行时检查:
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
实例扩展了一些超类?
public function careful(SomeClass:[Class extends SuperClass]):void
var instance:SuperClass = new SomeClass();
// all is good
【问题讨论】:
不太可能 - 虽然我不明白你为什么要这样实例化。为什么不先做function careful(instance:SuperClass)
然后做careful(new MySubClass())
,如果不是子类,它会在你身上编译时出错。
你需要使用你为某事创建的实例,还是你创建它只是为了检查它是否是一个子类?你能不能只传入一个你知道是子类的新创建的对象并使用它?
@mfa 可能有更好的方法来构建我正在处理的应用程序,但是按照所有设置的方式,我需要传入一个 Class 以便它可以通过以下方式多次实例化其他对象稍后。上面的具体代码只是为了展示一个简单的例子。
【参考方案1】:
如果你还是要实例化它,为什么不接受一个允许你输入:SuperClass
的对象呢?
careless(SomeClass);
//vs.
careless(new SomeClass);
就您的代码而言,这并不是什么大问题。 不过还是有一些区别:
必须创建对象,因为需要一个对象。如果您的函数在某些情况下没有实例化该类,这可能是个问题。传递对象或 null 的附加逻辑可能会使函数调用膨胀。 如果您不能在该函数之外调用构造函数,它不会 也可以工作。工厂模式解决了所有问题。传递一个工厂作为产生SuperClass
对象的参数。
function careful(factory:SuperClassFactory)
【讨论】:
我对工厂模式不是很熟悉 - 打算研究一下,因为它可能确实是我正在寻找的。span> 工厂模式正是我在这个应用程序中所需要的。谢谢!【参考方案2】:您的要求:
我只想接受扩展 SuperClass 的类
和
我需要传入一个类,这样它就可以被实例化多次 稍后由其他对象
可以通过传入你需要的类的实例,并使用 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.
【讨论】:
这是一个很好的解决方案。也许唯一的问题是它需要创建一个一次性实例?我最终使用工厂模式来解决我的特定问题,我认为这会让我不再需要使用它。不过,谢谢!【参考方案3】:在 ActionScript 3 中你不能这样做。在像 C# 这样的语言中你可以这样做(如果语法关闭,请原谅我):
public void Careless<T>() where T : SuperClass
但是 AS3 没有“泛型”。不幸的是,我知道如何做你想做的事情的唯一方法就是你已经做过的事情。
可能更适合您的用例的模式可能类似于:
class SuperClass
public static function careless():void
var instance:SuperClass = new SuperClass();
// ...
在 ActionScript 3 中进行静态类型检查的唯一方法是提供一个类的实例。
【讨论】:
【参考方案4】:这是可能的,但它很昂贵。您可以在类(而非实例)上使用:
flash.utils.describeType
然后,您将获得一个包含大量信息的 XML,包括该类的继承。就像我说的那样,这是一个昂贵的过程,并且可能在大多数情况下创建一个实例并检查它会更快。
【讨论】:
那是在运行时。 问题是基于运行时的,所有答案也是如此,你的意思是什么? 问题是问如何避免运行时检查,答案是尝试提供静态类型检查。 您自己的答案是基于运行时的。 PO 示例是基于运行时的。创建一个类的实例属于基于运行时的检查而不是编译时间。我的答案是您可以获得的最接近编译时检查的方法,因为它是唯一无需创建类实例即可工作的方法。 创建实例是基于运行时的,但如果在您的代码中您可能会创建错误类的实例,编译器会选择它,而您的示例需要在运行时检查 XML...你明白我的意思吗?以上是关于使用“类”数据类型时,如何指定类型以便只接受特定类的子类?的主要内容,如果未能解决你的问题,请参考以下文章
StringBuffer 类,以及 StringBuilder 类
Postgresql 运算符类“varchar_pattern_ops”不接受数据类型整数