将 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
类型转换为super
class。显然那是行不通的。
不,这不可能。
如果这是可能的,那么覆盖方法就不可能了!
比如拿这个函数...
public function test(a:Object):void {
trace(a.toString());
}
如果你的想法是事情如何运作,你只会得到 [object Object]
回报。
好的,我明白你的意思了,你的问题更多是关于语言定义和规范。
查看 c# 中的这个示例,它解释了如何在 c# 中更精确地管理覆盖:
但是
让我们稍微解释一下它是如何工作的。
当你扩展一个 class 时,就像你创建一个由继承树中的所有对象组成的对象,所以如果 B extends A
和 C 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 的情况下确定方法或 属性 是否存在。
我有这个:
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
类型转换为super
class。显然那是行不通的。
不,这不可能。
如果这是可能的,那么覆盖方法就不可能了!
比如拿这个函数...
public function test(a:Object):void {
trace(a.toString());
}
如果你的想法是事情如何运作,你只会得到 [object Object]
回报。
好的,我明白你的意思了,你的问题更多是关于语言定义和规范。
查看 c# 中的这个示例,它解释了如何在 c# 中更精确地管理覆盖:
但是 让我们稍微解释一下它是如何工作的。
当你扩展一个 class 时,就像你创建一个由继承树中的所有对象组成的对象,所以如果 B extends A
和 C 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 的情况下确定方法或 属性 是否存在。