0

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)
Decent Dabbler
  • 22,532
  • 8
  • 74
  • 106

3 Answers3

4

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

supercrabtree
  • 70
  • 1
  • 5
  • Thanks supercrabtree. This is actually how I had it implemented in the first place, but I was hoping I could circumvent the additional parameters for the Button's constructor. – Decent Dabbler Dec 15 '09 at 12:51
3

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;
    }
frankhermes
  • 4,720
  • 1
  • 22
  • 39
  • and if this alone doesn't do the trick, assign values to the padding vars in the constructor of Button class instead of doing it along with their variable declarations. – Amarghosh Dec 15 '09 at 10:47
  • Both your suggestions don't work, I'm afraid. As for frankhermes' suggestion: this makes sense, because I need the values altered before they are used in the supers constructor. – Decent Dabbler Dec 15 '09 at 11:11
  • you wanna use variable values before super class's constructor is executed? consider redesigning. – Amarghosh Dec 15 '09 at 12:28
  • Hmmm, I just created my example in PHP also and I think I had AS3's implementationt mixed up with the workings of PHP. Because in PHP my example is perfectly legal and works as I expect it to work. – Decent Dabbler Dec 15 '09 at 12:45
0

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.

analytik
  • 792
  • 6
  • 16