另一种选择是创建一个Movable
接口(纯虚拟类)来声明移动方法,并派生实现这些方法的子类:
Block Movable
| |
+-ColorBlock----------+-MovableColorBlock
| |
+-ImageBlock----------+-MovableImageBlock
编辑
是的,如果move()
子类之间的方法确实相同,那么这不是您想要的。
听起来该move()
操作与该操作正交draw()
,对我而言,这暗示了聚合而不是子类。所以让我们在这里稍微左转。
ABlock
有一个位置;也许位置参数可能是可移动的或不可移动的:
class Position
{
public:
Position( int x, int y ) : m_x(x), m_y(y) { }
virtual ~Position() {}
int getX() const { return m_x; }
int getY() const { return m_y; }
virtual bool movable() const { return false; }
protected:
int m_x;
int m_y;
};
class MovablePosition : public Position
{
public:
MovablePosition( int x, int y ) : Position( x, y ) {}
virtual ~MovablePosition() {}
void move( int newX, int newY ) { m_x = newX; m_y = newY; }
virtual bool movable() const { return true; }
};
然后您的基Block
类将 aPosition
作为参数:
class Block
{
public:
Block( Position *p ) : m_pos( p ) {}
virtual ~Block() {}
virtual void draw() = 0;
Position *getPos() const { return m_pos; }
protected:
Position *m_pos;
};
然后如果你想移动一个Block
子类实例,你首先要检查movable()
方法:
if ( myColorBlock.getPos()->movable() )
{
MovablePosition *p = myColorBlock.getPos();
p->move( newX, newY );
myColorBlock.draw();
}
无需创建冗余MovableXxxBlock
类,无需重复代码。在这种方案下,块的可移动性是在运行时而不是编译时建立的;这可能与您的目标兼容,也可能不兼容。