AS3 Casting as SuperClass返回null

时间:2013-07-10 17:04:43

标签: actionscript-3 inheritance casting subclass

  

解决方案!   确保您没有错误地导入错误的类。

     

就我而言,我是明确导入TabButton,但有   另一个正在导入的TabButton类,因为它存在于   与TabButtonSubclass相同的目录。这是因为   TabButtonSubclass存在于特定于一个应用程序的文件夹中。这个   文件夹还包含一个可怕的通用命名类TabButton,   这与其他TabButton完全不相关且不兼容   类。特定于应用程序的TabButton类已重命名,因此它是   显然它属于那个应用程序。

     

如果我写了'公共类MBTabButtonSprited扩展 [具体   位置] .TabButton',它会运行良好。但似乎是这样   因为'extends TabButton'没有以特定路径开头,所以   编译器默认为本地路径。

我一直在我的桌子上敲了一会儿,试图弄清楚这个。

我的问题是我已经扩展了Sprite来创建一个TabButton类。然后,我扩展了TabButton类(我们称之为TabButtonSubclass)以获得一些额外的功能。当我尝试将TabButtonSubclass的实例强制转换为TabButton时,我得到null。

奇怪的是,我可以将TabButton TabButtonSubclass的实例转换为Sprite,并且它可以正常工作。

以下是我的TabButton的样子:

import flash.display.Sprite;

public class TabButton extends Sprite {
    public function TabButton():void {
        super();
        // code
    }
}

以下是我的TabButtonSubclass的样子:

import ...TabButton;

public class TabButtonSubclass extends TabButton {

    public function TabButtonSubclass( bitmap:BitmapData ):void {
        // code
        super();
    }

}

澄清TabButtonSubclass类:扩展TabButton的目的是使用提供的Bitmap实例化TabButtonSubclass。此位图将用于各种目的。我在过去扩展了类并为构造函数添加了参数,并且工作正常。这不是个好主意吗?

一些示例代码说明了我的问题:

import flash.display.Sprite;
import ...TabButton;
import ...TabButtonSubclass;

var btn1:TabButton = new TabButton();
trace( "btn1:", btn1 );     // btn1: [object TabButton]
trace( "btn1 as Sprite:", (btn1 as Sprite) );     // btn1 as Sprite: [object TabButton]

var btn2:TabButtonSubclass = new TabButtonSubclass( new GangTabMail() );
trace( "btn2:", (btn2) );     // btn2: [object TabButtonSubclass]
trace( "btn2 as TabButton:", (btn2 as TabButton) );     // btn2 as TabButton: null
trace( "btn2 as Sprite:", (btn2 as Sprite) );     // btn2 as Sprite: [object TabButtonSubclass]

正如你所看到的,我能够将btn1作为Sprite投射而没有任何问题。我也可以将btn2转换为Sprite,并返回预期的结果。但是,如果我尝试将TabButtonSubclass的实例强制转换为TabButton,它将返回null。

我有兴趣将TabButtonSubclass的实例转换为TabButton,因为该应用程序使用了几个类,需要传递TabButton类型的对象。

以下是一些代码的示例,它允许您将类键入为超类:

import ...TabButton;
import flash.display.Sprite;

var myBtn:TabButton = new TabButton();
doStuff( myBtn );     // btn: [object TabButton]

function doStuff( btn:Sprite ):void {
    trace( "btn:", btn );
}

以下是代码失败的示例,如果您更深入一级:

import ...TabButton;
import ...TabButtonSubclass;
import flash.display.Sprite;

var myBtn:TabButtonSubclass = new TabButtonSubclass( new BitmapData( ... ) );
doStuff( myBtn );     // Returns error: Implicit coercion of a value of type ...:TabButtonSubclass to an unrelated type ...:TabButton
doStuff( myBtn as TabButton );     // btn: null

function doStuff( btn:TabButton ):void {
    trace( "btn:", btn );
}

当我试图追踪它时,是否有人可以提供任何帮助以获得空响应?或者为什么我会收到这个错误?我是否遗漏了关于子类和类型转换的内容?

4 个答案:

答案 0 :(得分:1)

我不确定它为什么会返回null,但我处理它的方式是使用基类定义变量并在需要时进行转换,例如。

import ...TabButton;
import ...TabButtonSubclass;
import flash.display.Sprite;

var myBtn:TabButton = new TabButtonSubclass( new BitmapData( ... ) );
doStuff( myBtn ); // No need to case here since myBtn is already defined as TabButton

function doStuff( btn:TabButton ):void {
    trace( "btn:", btn );
}

然后,如果您需要TabButtonSubclass功能,则将其强制转换:

var myBtnSub:TabButtonSubclass = myBtn as TabButtonSubclass;

答案 1 :(得分:0)

我不是AS3的专家并且还在学习,但也许这可以帮助:

在您的上一段代码段中,当您执行

doStuff( myBtn );

doStuff( myBtn as TabButton);

当你正在使用类型为TabButtonSubclass的变量时,你正在传递一个类型为TabButton的变量。这就是为什么你得到关于隐式强制的第一个错误。

现在,如果你将变量cast作为TabButton传递给函数时,你得到一个null的原因,我不是很确定,但我认为这与它有关如果cast不能被“尊重”(即,你告诉编译器该演员是有效的,但事实证明它实际上不是,就像你试图将XML数据转换为影片剪辑一样)例如),那么结果将为null。

希望有所帮助,但我可能完全错了!

答案 2 :(得分:0)

您的代码应该可以正常运行。然而,当您将一个函数参数类型声明为Class时,这不是其他称为“最佳实践”的内容。您的TabButton应该有界面

您可以对象传递给您的函数,但有一个例外:对象必须具有所有已实现的方法,您的界面具有此功能。而已。见Polymorphism


您的问题的一个可能答案是:

public class TabButtonSubclass extends TabButton {

TabButton TabButton 不同

trace( "btn2 as TabButton:", (btn2 as TabButton) ); // btn2 as TabButton: null

强制转换与 as 运算符之间的关键区别在于失败时的行为。当转换失败时,抛出TypeError。使用 as 运算符,只要转换失败,就会返回数据类型的默认值。 read more...

答案 3 :(得分:0)

确保您没有错误地导入错误的课程。

就我而言,我是显式导入TabButton,但是还有另一个TabButton类被导入,因为它存在于与TabButtonSubclass相同的目录中。发生这种情况是因为TabButtonSubclass存在于特定于一个应用程序的文件夹中。此文件夹还包含一个可怕的通用命名类TabButton,它与其他TabButton类完全不相关且不兼容。特定于应用程序的TabButton类已重命名,因此很明显它属于该应用程序。

如果我写了'公共类MBTabButtonSprited扩展 [特定位置]。 TabButton',它本来可以正常工作。但似乎因为'extends TabButton'没有以特定路径开头,编译器默认为本地路径。