假设我们有三个类Button
、Clickable
和Rectangle
它们都不是抽象的,可以独立存在。它们都有一个position
成员变量。当Button
类从Clickable
和Rectangle
继承时,它们应该共享一个公共的position
变量
我的实现:
struct Positionable {
struct Position {
int x, y;
} position;
};
struct Rectangle: virtual public Positionable {
// ...
};
struct Clickable : virtual public Positionable {
// ...
};
struct Button : virtual public Positionable, public Rectangle, public Clickable {
Button() {
this->position.x = 1;
assert(Rectangle::position.x == 1);
assert(Clickable::position.x == 1);
assert(Positionable::position.x == 1);
}
} test;
这个问题(除了单词position的三种形式之外(是,我觉得我打破了组合而非继承原则,因为我继承只是为了包含一个变量
是否存在具有相同行为的设计模式?在这种情况下我该如何使用作文?
编辑:
我正在寻找一种Button
继承自Clickable
和Rectangle
的解决方案,因为这是一种is-a关系。(这可能不是最好的例子,但假设这是真的(
我也不想从Positionable
继承,因为这是一个has-a关系
我想要与我的实现相同的行为,所以:
- 他们都有一个
Position position
- 当它们相互继承时,它们共享此变量
- 我不使用setter/getter
基本上我想要像虚拟变量这样的东西,但c++还没有这个功能,所以我正在寻找一个合理的替代品。
我并不完全理解您的问题,但是您可以使用引用来实现这一点。你可以做一些类似的事情:
struct Position{
int x,y;
};
class Rectangle {
public:
Rectangle(Position& p) : pos(p) {}
~Rectangle() {}
Position getPos(){ return pos; }
protected:
Position& pos;
};
class Clickable {
public:
Clickable(Position& p) : pos(p) {}
~Clickable() {}
Position getPos(){ return pos; }
protected:
Position& pos;
};
class Button {
public:
Button(int x, int y) : pos({x,y}), a(this->pos), b(this->pos) {}
~Button() {}
Position getPos(){ return pos; }
protected:
Position pos;
Clickable a;
Rectangle b;
};
不过这很乱。如果你问我的话,使用原始的Rectangle
和Clickable
类也会很痛苦。如果你喜欢的话,指针也可以实现这一点。
继承为is-a关系建模。如果Horse
继承自Animal
,那么Horse
就是Animal
,因为动物的所有特性也是马的特性。
现在,在您的例子中,说Button
就是Clickable
有意义吗?是的,因此继承是适用于作业的工具。说Button
就是Rectangle
有意义吗?好吧,现在我们陷入了浑水。
如果我们打算通过Rectangle
子接口使用Button
(也许一个简单的渲染器可以接受矩形派生对象并渲染它们(,那么继承在这里也是合适的。但是,如果使用继承是因为它是正确的OOP,并且这是需要做的,那么不。
权衡一下你需要什么,看看它是否合乎逻辑。先考虑是否应该,然后再考虑是否可以。
附言:我不明白Clickable
为什么不抽象。这听起来像是一个界面。如果它不是一个接口,那么您试图建模的概念可能有一个更好的名称。
编辑
我突然想到,如果您使用C++,您可能需要研究private
继承。这就是您正在讨论的实现继承。C++常见问题解答:https://isocpp.org/wiki/faq/private-inheritance