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
精彩评论