English 中文(简体)
AS3: overriding protected var in subclass
原标题:

I m having a blackout here. I thought I understood these principles, but I can t seem to get it working anymore. I want to let a DeleteButton inherit from a general Button class. This DeleteButton should alter the protected padding values and have a static label. This is what I have:

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  );
    }
}

Now, I thought the altered _paddingX and _paddingY values in the inherited class would bubble up to the super class. But they don t. The DeleteButton is still constructed with the default values of the super class. I can t figure out how to do it anymore. What am I missing here?

Thanks in advance.

Edit:

I guess I had AS3 s implementation mixed up with PHP s. This equivalent example in PHP is perfectly legal:

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)
最佳回答

when you call the super() function you also initialise all of the super classes variables. So in your example when you call..

_paddingX = 5;
_paddingY = 2;

..before calling super(), you are actually creating arbitrary values inside that function. So you re getting it right its just that those variables dont exist until the super() function has been called.

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 );

    }
}

Do this instead, this way you can keep the default values, as 10 and 5, but change them if needed. Now if you call this on the main timeline you it should work for you.

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

Hope this explains it :)

George

问题回答

I think calling super( x ) before setting the _paddingX and _paddingY could make a difference:

 public function DeleteButton():void
    {
        super(  x  );

        _paddingX = 5;
        _paddingY = 2;
    }

What you could do is to override getters:

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;
    }
}

The parent Button constructor will now use the overridden getter from child DeleteButton class.

You could also set _paddingX/Y to private to hide them from the implementation, and add new _paddingX/Y in DeleteButton. This however, seems like a dirty practice, because the properties in DeleteButton aren t enforced by API.





相关问题
Attaching a property to an event in Flex/AS3

I have a parameter that needs to be passed along with an event. After unsuccessful attempts to place it on the type by extending the class, I ve been advised in another SO question to write a custom ...

Sorting twodimensional Array in AS3

So, i have a two-dimensional Array of ID s and vote count - voteArray[i][0] = ID, voteArray[i][1] = vote count I want the top 3 voted items to be displayed in different colors, so i have a 2nd Array -...

Virtual Tour using sketch up, ajax, flash technologies

I want to know if there are existing technology that make your 3d models in sketch into virtual tours, using either Ajax or Flash for web presentation. If there s none, which will be a good approach ...

What s a good way of deserializing data into mock objects?

I m writing a mock backend service for my flex application. Because I will likely need to add/edit/modify the mock data over time, I d prefer not to generate the data in code like this: var mockData =...

AS3 try/catch out of memory

I m loading a few huge images on my flex/as3 app, but I can t manage to catch the error when the flash player runs out of memory. Here is the what I was thinking might work (I use ???? because i dont ...

热门标签