在Flex/ActionScript3中实现抽象类及继承机制解密
ActionScript3中没有抽象类的概念。但是,在Flex提供的类库中,有些类却实现类抽象类的功能。
如:
DisplayObjectContainer | 属性 | 方法 | 事件 | 示例 |
包 | flash.display |
类 | public class DisplayObjectContainer |
继承 | DisplayObjectContainer InteractiveObject DisplayObject EventDispatcher Object |
子类 | Loader, Sprite, Stage |
语言版本 : | ActionScript 3.0 |
Player 版本 : | Flash Player 9 |
DisplayObjectContainer 类是可用作显示列表中显示对象容器的所有对象的基类。该显示列表管理 Flash Player 中显示的所有对象。 使用 DisplayObjectContainer 类排列显示列表中的显示对象。 每个 DisplayObjectContainer 对象都有自己的子级列表,用于组织对象的 Z 轴顺序。 Z 轴顺序是由前至后的顺序,可确定哪个对象绘制在前,哪个对象绘制在后等。
DisplayObject 是一种抽象基类;因此,不能直接调用 DisplayObject。 调用 new DisplayObject() 会引发 ArgumentError 异常。
DisplayObjectContainer 类是可以包含子对象的所有对象的抽象基类。无法直接对其进行实例化;调用 new DisplayObjectContainer() 构造函数会引发 ArgumentError 异常。
这是怎样实现的呢?我下载了Adobe Flex在SVN上的所有源代码。但是没有找到类库的源代码。我想可能这些核心API的源代码还没有开源吧?
后来我终于发现了DisplayObjectContainer类的实现机制。它们可能是这样实现的。
让我们先看一下这种技术的一个例子吧:
基类:------抽象基类,不可以实例化。
package
{
public class Base
{
public function Base(self:Base)
{
if(self!=this){
//TODO: implement function
throw new ArgumentError("Can't new Base instance!");
}
}
public function say(){
return "Base say";
}
}
}
子类: 可以实例化
package
{
public class Extend extends Base
{
public function Extend()
{
//TODO: implement function
super(this);
}
public override function say(){
return "Extend say";
}
}
}
如果你试图直接new Base(),就会抛出异常,阻止你实例化Base类。
但是如果你new Extend(),就可以实现。
也许你会说,直接把Base类的构造器声明为private不就行了吗?
但是,ActionScript3的语法规定,类的构造器只能声明为public。
也许你想在Java中也试验一下这种技术,答案是no way!
在Java中,构造器中不能调用this和super对象。在C#和C++中也一样。
因为,构造函数执行时,对象还没有创建,所以不能调用this或super对象。
但为什么ActionScript3的构造函数就可以呢?
因为ActionScript3和java、C++、C#等传统语言的继承机制的实现原理不同。
ActionScript3的继承机制,本质上是原型继承。就是类似于JavaScript那样的继承方式。ActionScript3在创建对象时,首先创建子类的实例,然后通过调用super()创建基类的实例,然后通过对象引用把它们联系起来。
因此,可以在ActionScript3的构造器中使用this。
而C++,Java等语言,是在一块内存块中创建基类和子类的对象。因此,在构造器执行完毕之前,根本不能调用this或super。因为这些对象都还没有创建完成呢。