【问题标题】:AS3: overriding protected var in subclassAS3:覆盖子类中的受保护变量
【发布时间】:2023-12-25 18:21:02
【问题描述】:

我这里停电了。我以为我理解了这些原则,但我似乎无法让它发挥作用了。我想让 DeleteButton 从一般的 Button 类继承。此 DeleteButton 应更改受保护的填充值并具有静态标签。这就是我所拥有的:

public class Button
{
    private var _labelText:String;

    protected var _paddingX:Number = 10;
    protected var _paddingY:Number = 5;

    public function Button( labelText:String ):void
    {
        _labelText = labelText;
    }
}

public class DeleteButton extends Button
{
    public function DeleteButton():void
    {
        _paddingX = 5;
        _paddingY = 2;

        super( 'x' );
    }
}

现在,我认为继承类中更改的 _paddingX 和 _paddingY 值会冒泡到超类。但他们没有。 DeleteButton 仍然使用超类的默认值构造。我不知道该怎么做。我在这里错过了什么?

提前致谢。

编辑:

我猜我将 AS3 的实现与 PHP 的实现混在一起了。 PHP 中的这个“等效”示例是完全合法的:

class Button
{

    protected $_paddingX = 10;
    protected $_paddingY = 5;

    public function __construct( $label = '' )
    {
        var_dump( $label . ':' );
        var_dump( $this->_paddingX );
        var_dump( $this->_paddingY );
        echo '<br>';
    }
}

class DeleteButton extends Button
{
    public function __construct()
    {
        $this->_paddingX = 5;
        $this->_paddingY = 2;

        parent::__construct( 'x' );
    }
}

$button = new Button( 'browse' );
$deleteButton = new DeleteButton();

// this outputs:
string(7) "browse:" int(10) int(5) 
string(2) "x:" int(5) int(2)

【问题讨论】:

    标签: actionscript-3 overriding protected


    【解决方案1】:

    当您调用 super() 函数时,您还初始化了所有超类变量。所以在你打电话的例子中..

    _paddingX = 5;
    _paddingY = 2;
    

    ..在调用 super() 之前,您实际上是在该函数中创建任意值。所以你做对了,只是在调用 super() 函数之前这些变量不存在。

    public class Button
    {
        private var _labelText:String;
    
        protected var _paddingX:Number;
        protected var _paddingY:Number;
    
        public function Button( labelText:String, paddingX:Number=10, paddingY:Number=5 ):void
        {
            _paddingX = paddingX;
            _paddingY = paddingY;
    
            _labelText = labelText;
        }
        public function traceVars():void {
            trace(_labelText);
            trace(_paddingX);
            trace(_paddingY);
        }
    }
    
    public class DeleteButton extends Button
    {
        public function DeleteButton():void
        {
            super( 'x', 5, 2 );
    
        }
    }
    

    改为这样做,这样您可以保留默认值,如 10 和 5,但如果需要,可以更改它们。现在,如果您在主时间线上调用它,它应该适合您。

    var but:DeleteButton = new DeleteButton();
    but.traceVars();
    

    希望这能解释它:)

    乔治

    【讨论】:

    • 感谢 supercrabtree。这实际上是我最初实现它的方式,但我希望我可以绕过 Button 构造函数的附加参数。
    【解决方案2】:

    我认为在设置 _paddingX 和 _paddingY 之前调用 super('x') 可能会有所作为:

     public function DeleteButton():void
        {
            super( 'x' );
    
            _paddingX = 5;
            _paddingY = 2;
        }
    

    【讨论】:

    • 如果仅此一项不能解决问题,请在 Button 类的构造函数中为填充变量赋值,而不是与变量声明一起进行。
    • 恐怕你的两个建议都行不通。至于 frankhermes 的建议:这是有道理的,因为我需要在将值用于 supers 构造函数之前对其进行更改。
    • 你想在超类的构造函数执行之前使用变量值吗?考虑重新设计。
    • 嗯,我刚刚也在 PHP 中创建了我的示例,我认为我将 AS3 的实现与 PHP 的工作混为一谈。因为在 PHP 中,我的示例是完全合法的,并且可以按我的预期工作。
    【解决方案3】:

    你可以做的是覆盖getter:

    public class Button
    {
        private var _labelText:String;
    
        protected var _paddingX:Number = 10;
        protected var _paddingY:Number = 5;
    
        public function Button( labelText:String ):void
        {
            _labelText = labelText;
        }
    
        protected function get paddingX():Number
        {
            return _paddingX;
        }
        // get paddingY ommited for brevity
    }
    
    public class DeleteButton extends Button
    {
        public function DeleteButton():void
        {
            super( 'x' );
        }
    
        override protected function get paddingX():Number
        {
            return 42;
        }
    }
    

    父 Button 构造函数现在将使用来自子 DeleteButton 类的重写 getter。

    您还可以将 _paddingX/Y 设置为私有以对实现隐藏它们,并在 DeleteButton 中添加新的 _paddingX/Y。然而,这似乎是一种肮脏的做法,因为 DeleteButton 中的属性不是由 API 强制执行的。

    【讨论】:

      最近更新 更多