开发者

How do you manage this inheritance problem?

开发者 https://www.devze.com 2023-01-23 10:05 出处:网络
Lets\'s say you have 2 classes ToolBar and DrawingToolBar. ToolBar is to serve as a base class for various other toolbars, for various tools. ToolBar handles the basic \'toolbar-y\' stuff like opening

Lets's say you have 2 classes ToolBar and DrawingToolBar. ToolBar is to serve as a base class for various other toolbars, for various tools. ToolBar handles the basic 'toolbar-y' stuff like opening, closing, dragging, dropping, etc. The DrawingToolBar adds functionality that is specific to a particular tool - tool-specific buttons, etc.

public class ToolBar extends Sprite {
    public var closeBtn:Sprite

    public function ToolBar():void {
        addChild(closeBtn)
        closeBtn.addEventListener(MouseEvent.CLICK, closeBtn_onClick)
    }

    protected function closeBtn_onClick(e:Event):void {
        close()
    }

    public function open():void {
        // blah
    }

    public function close():void {
        // blah
    }
}

and:

public class DrawingToolBar extends ToolBar{

    public var penBtn: Sprite
    public var paintbrushBtn: Sprite
    public var colorPicker: ColorPicker

    public function DrawingToolBar():void {
        super()     
    }

    public function getColour():int {
        return colorPicker.color;
    }
}

Now, we also have another 2 classes - Tool and DrawingTool. Again, Tool is a base class for various tools (incl. DrawingTool). If I make a ToolBar member in Tool (typed as ToolBar), we can delegate common tasks, eg. when the Tool is enabled, it adds the ToolBar to the stage, etc. The DrawingTool can instantiate the ToolBar as a DrawingToolBar so the correct library asset is used (but the instance is still typed as ToolBar).

public class Tool {
    public var toolBar:ToolBar

    public function Tool():void {
        initToolBar()       
    }

    protected function initToolBar():void {

        addChild(toolBar)

    }   
}

and:

public class DrawingTool extends Tool {
    public function DrawingTool():void {
        super()     
    }

    override protected function initToolBar():void {
        toolbar = new DrawingToolBar() // this is probably very naughty 
        super.initToolBar()
    }

    public function getColor():int {

        return toolBar.getColor() // this fails because toolBar is type as ToolBar not DrawingToolBar
    }
}

T开发者_运维知识库he problem comes when, in DrawingTool I want to call a method of DrawingToolBar. Because the toolbar is typed as ToolBar, I can't call methods of DrawingToolBar on it. What do I do?

  • cast it every time I want to call a method of DrawingToolBar?
  • create a member in DrawingTool (eg. var drawingToolBar: DrawingToolBar), instantiate that and then make toolBar = drawingToolBar?

The first seems clunky, I don't even know if it would work. The second seems better but it feels a bit 'wrong'.

Is there another way? Or am I mis-using inheritance here?


You are probably mixing too many functionnalities into your toolbar. If you think MVC, you are missing a Model.

More precisely, the color picker should not be a property of your toolbar. The color picker is a property of your tool. Each drawing tool should be self contained and have its own color picker. If all drawing tools need to share the same color, you'll need a Drawing model that is shared by all drawing tools.

I would also change the relation between the Toolbar and its tools in the other direction. A toolbar has tools, but the tools themselves should be self contained and not have a reference to their containing toolbar.

The Java / Swing model is very clean on how it works with toolbars. You could get some inspiration from it : http://download.oracle.com/javase/tutorial/uiswing/components/toolbar.html

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号