1、如果在构造函数中没有显示指出super,将自动在构造函数开始部分调用super父构造。
调用new Son,输出:package
{
public class Father
{
public function Father()
{
trace("父构造");
}
}
}
package
{
public class Son extends Father
{
public function Son()
{
trace("子构造");
}
}
}
父构造
子构造
2、super父构造不一定非要放在构造函数开始部分。
如果在父构造函数中可能调用某些子类中覆盖了的方法,而子类的该方法中某些变量实在构造函数中初始化的,可以考虑把super移到构造函数尾部执行。
调用 new Son,报错:package
{
public class Father
{
private var _width:Number;
public function Father()
{
trace("父构造");
width = 10;
}
protected function set width(value:Number):void
{
_width = value;
}
}
}
package
{
import flash.text.TextField;
public class Son extends Father
{
private var txt:TextField;
public function Son()
{
trace("子构造");
txt = new TextField();
//super();
}
protected override function set width(value:Number):void
{
super.width = value;
txt.width = value;
}
}
}
而把super()前的注释喀掉,运行ok。TypeError: Error #1009: 无法访问空对象引用的属性或方法。
at Son/set width()
at Father()
at Son()
3、如果在类定义中,对成员变量定义了初始值,这些成员变量的定义将先于构造函数中的语句执行。
考虑如果子类继承了父类的某个成员变量,想在构造构造函数中对该变量重赋值,如果恰巧父类定义中声明该变量时给了初始值,而且子类中重赋值后才调用父构造函数,运行结果将是出乎你的意愿。
调用new Son,输出package
{
public class Father
{
protected var _name:String = "father";
public function Father()
{
}
}
}
package
{
public class Son extends Father
{
public function Son()
{
_name = "son";
trace(_name);
super();
trace(_name);
}
}
}
son
father
总结下,构造函数执行顺序如下: