[英]Preferring composition over inheritance in the diamond problem
假設我們有 3 個類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的 3 種形式)是我覺得我打破了繼承原則的組合,因為我繼承只包含一個變量。
是否有具有相同行為的設計模式? 在這種情況下如何使用組合?
我正在尋找一種解決方案,其中Button
繼承自Clickable
和Rectangle
,因為它是一種 is-a 關系。 (這可能不是最好的例子,但假設它是真的)
我也不想從Positionable
繼承,因為它是一個 has-a 關系。
我想要與我的實現相同的行為,所以:
Position position
基本上我想要像虛擬變量這樣的東西,但是 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
類也很痛苦。 如果您喜歡,指針也可以實現這一點。
繼承模型是一種關系。 如果Horse
繼承自Animal
,那么Horse
就是Animal
,因為動物擁有的所有屬性也是馬的屬性。
現在,在您的示例中,說Button
是可Clickable
是否有意義? 是的,所以繼承是這項工作的適用工具。 說Button
是Rectangle
有意義嗎? 好吧,現在我們陷入了泥濘的水域。
如果我們打算通過Button
的Rectangle
子接口使用它(也許一個簡單的渲染器可以接收矩形派生對象並渲染它們),那么在這里繼承也是合適的。 但是,如果使用繼承是因為它是正確的 OOP 並且這是需要做的事情,那么不。
權衡你需要什么,看看它是否合乎邏輯。 先想想是否應該,然后再考慮是否可以。
PS:我不明白為什么Clickable
不是抽象的。 這聽起來像一個界面。 如果它不是接口,那么您嘗試建模的概念可能有一個更好的名稱。
編輯
我突然想到,如果您使用 C++,您可能需要研究private
繼承。 這就是你所說的實現繼承。 C++ 常見問題解答: https : //isocpp.org/wiki/faq/private-inheritance
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.