将 super 分配给 AS3 中的变量

Assign super to variable in AS3

我有这个:

public class Base {
    public function whoAmI() {
        trace("base");
    }
}

public class Extended extends Base {

    public function Extended() {
        this.whoAmI() //prints extended
        super.whoAmI() //prints base

        var test = super;
        test.whoAmI() //prints extended
    }

    public override function whoAmI() {
        trace("extended");
    }
}

问题是当我执行 var test = super 时,似乎 this 被分配给测试而不是 super

是否可以进行赋值,以便 test.whoAmI() 打印出 "base"?

编辑:在评论中有人说按照我建议的方式使用 super 会破坏覆盖。我不认为是这样。我的想法是,super 可以像 this 一样使用。我知道这不是 super 的实现方式,但是以这种方式使用它不会像人们声称的那样破坏压倒一切。因此,例如以同样的方式这是可能的:

var test = this;
test.whoAmI();

这应该是可能的:

var test = super;
super.whoAmI();

很明显语言实现者选择不这样做,我不明白为什么。它不会破坏东西,但我想它确实会让它们变得更复杂。

建议将this类型转换为superclass。显然那是行不通的。

不,这不可能。

如果这是可能的,那么覆盖方法就不可能了!


比如拿这个函数...

public function test(a:Object):void {
    trace(a.toString());
}

如果你的想法是事情如何运作,你只会得到 [object Object] 回报。

好的,我明白你的意思了,你的问题更多是关于语言定义和规范。

查看 c# 中的这个示例,它解释了如何在 c# 中更精确地管理覆盖:

http://www.dotnet-tricks.com/Tutorial/csharp/U33Y020413-Understanding-virtual,-override-and-new-keyword-in-C

但是 让我们稍微解释一下它是如何工作的。

当你扩展一个 class 时,就像你创建一个由继承树中的所有对象组成的对象,所以如果 B extends AC extends B 你有两个像这样的对象:

(B+A) 和 (C+B+A) 彼此之间具有层次结构 B->A 和 C->B->A。 super只是一种晋升的方式。

例如,当您在 A 中投出 C 时。在内存中,您总是有一个对象 (C+B+A) 但被解释为 A。当您覆盖时,您只是说子项中的方法比父项中的方法具有更高的优先级。

您将 "this" 和 "super" 视为 2 个不同的实例,2 个不同的事物,但它们实际上指向同一个对象(显然),所以最后总是 "this".使用 super 只是一个特殊的关键字,它允许实例指向继承链上的重写定义,它不指向不同的对象。所以 "super" 正确地完成了它的工作,它指向实例并允许你每次使用它来访问覆盖的定义,就是这样。当然,尝试将该关键字存储在变量中是没有意义的,因为在这种情况下,它只是 return 正确地指向它指向的实例始终是 "this"。 这只是一个被误解的继承原则的例子,我以前见过它,super 被误认为是围绕对象 "this" 的继承链的某种实例包装器,而实际上它总是同一个对象。

您可以尝试将 this 手动向下转换为 class 的任何前任。指针仍然等于 this 但调用的方法将使用 class 的 class table 用于向下转换。

public class Extended extends Base {

    public function Extended() {
        this.whoAmI() //prints extended
        super.whoAmI() //prints base

        var test:Base = this;
        test.whoAmI() //should print base
    }

    public override function whoAmI() {
        trace("extended");
    }
}

如果你的 Base 扩展一些东西,哪些方法是已知的 superclass 是 dynamic,并且有添加的代码class 的 prototype 的方法,你可以使用这样的向下转换来调用编译时可能不存在的超级 class 的方法,但请确保你首先调用 hasOwnProperty 在动态 class 的情况下确定方法或 属性 是否存在。