Choice for class design
我有一个典型的课堂设计问题,我想听听你的意见。
让我们想象一下,我有一个基础类动物。从这一类中,我衍生出几种特定的动物。我对他们之间的互动很感兴趣。由于它们之间的交互可能因动物而异,所以我所做的就是用纯虚拟函数(即抽象类)创建基类:
class dog;
class cat;
class bird;
class Animal{
private:
int legs;
public:
virtual void Interact(const dog &) = 0;
virtual void Interact(const cat &) = 0;
virtual void Interact(const bird &) = 0;
};
然后,对于每个特定的动物,我从动物类创建一个派生类。例如:
class dog: public Animal{
// Implementation of interaction with other animals:
void Interact(const dog & object) {...body...};
void Interact(const cat & object) {...body...};
void Interact(const bird & object) {...body...};
};
类似于猫和鸟的课程。现在我关心的是鸟类课程。鸟类可以飞行,并有狗和猫没有的额外变量/方法。什么是一个聪明的方法来管理它?例如,一种蛮力的方法是向基础类动物添加额外的方法和变量,如
class FlyingAnimal: public Animal{
private:
int wings;
public:
void Fly();
};
然后我可以用这只鸟而不是动物来创造类鸟:
class Bird: public FlyingAnimal{
body and definition of void Interact(...)...
};
你觉得怎么样?也许你还有别的建议。
非常感谢!XDOF
当你只有三个班时,对其他可能的动物使用不同的交互方法是可行的,但是当你添加老鼠、兔子、老虎、老鼠、附魔、袋熊、海豚、犰狳和斑马时,它会很快变得笨拙,因为每当你添加一个新的动物时,你需要编辑每个现有的班来添加一个新的交互方法。这不是面向对象编程的方式。OOP的目的是您可以简单地添加一个新类,并且所有其他类都可以立即使用它,而不需要任何修改。
出于这个原因,您应该以更一般化的方式处理交互。为什么猫猎杀老鼠或鸟,而不是狗?当我面对一只带着微笑的猫时会发生什么?(笑是一种小的、毛绒绒绒的、四条腿的、食草的哺乳动物,大约5厘米长,我刚刚编了一个
当您将一个抽象的
1 2 3 4 5 6 | void Cat::interact(const Animal & other) { if (other.getSpeed() < this.getSpeed() && other.getSize() < this.getSize()) { this.eat(other); } } |
它可以应用于你创造的任何新动物。猫类将不再依赖于其他所有的动物子类。它只取决于动物,它提供了决定是否吃其他动物的所有重要方法。
我认为你做错的第一件事是在基类的接口中有派生类。你应该使用访客模式。您可以为三个动物类创建通用交互访问者或三个单独的访问者。然后提供要作为构造函数参数进行交互的动物。