C++;一个简单场景的OO继承正确性 我试图用C++的简单模型创建一个继承层次:课程、模块和课程,其中课程由零或更多的模块组成,模块由零或更多的课程组成。 每个类别还包含其他信息: class course { private: const std:string & name_; const std::duration duration_; const difficulty difficulty_; ... }; class module { private: const std:string & name; const std::duration duration; ... }; class lesson { private: const std:string & name; const std::duration duration; ... };
我的问题是:C++;一个简单场景的OO继承正确性 我试图用C++的简单模型创建一个继承层次:课程、模块和课程,其中课程由零或更多的模块组成,模块由零或更多的课程组成。 每个类别还包含其他信息: class course { private: const std:string & name_; const std::duration duration_; const difficulty difficulty_; ... }; class module { private: const std:string & name; const std::duration duration; ... }; class lesson { private: const std:string & name; const std::duration duration; ... };,c++,oop,inheritance,C++,Oop,Inheritance,我的问题是: 有这样一个类是正确的吗?这三个类都是从这个类继承的,它包含它们的公共属性 就我个人而言,我认为以以下方式从Vector继承会更为正确: class course : public std::vector<module> { private: const std:string & name_; const std::duration duration_; const difficulty difficulty_; ... };
- 有这样一个类是正确的吗?这三个类都是从这个类继承的,它包含它们的公共属性
class course : public std::vector<module>
{
private:
const std:string & name_;
const std::duration duration_;
const difficulty difficulty_;
...
};
class module : public std::vector<lesson>
{
private:
const std:string & name;
const std::duration duration;
...
};
class lesson
{
private:
const std:string & name;
const std::duration duration;
...
};
课程:公共std::vector
{
私人:
常量标准:字符串和名称;
const std::持续时间;
常量难度;
...
};
类模块:公共std::vector
{
私人:
常量标准:字符串和名称;
const std::持续时间;
...
};
课堂
{
私人:
常量标准:字符串和名称;
const std::持续时间;
...
};
由于课程是模块的集合,而模块是具有一些附加属性的课程集合,因此从vector继承将提供添加、删除等模块和课程所需的所有标准功能
- 为什么不能两者兼而有之?我在学校学习继承的方式,使用Java,我被教导多重继承是邪恶的,为了正确的OO继承而远离多重继承,使用等等。有很多人不相信多重继承,还有很多人对多重继承深信不疑
class course : public namedentity
{
private:
std::vector<module> modules_;
...
const difficulty difficulty_;
...
};
class module : public namedentity
{
private:
std::vector<lesson> lesons_;
...
};
class lesson : public namedentity
{
private:
...
};
课程类别:公共名称身份
{
私人:
向量模;
...
常量难度;
...
};
类模块:公共名称身份
{
私人:
std::向量lesons;
...
};
课程:公共名称身份
{
私人:
...
};
其中namedentity包含所有公共属性,这些私有向量包含它们的子属性
我想归根结底,课程真的是
vector
,模块真的是vector
?这是否违反LSP或其他OO原则?将孩子作为财产会更好吗?不建议公开继承向量,因为课程、课程或模块不是向量
碰巧您使用向量来实现它们,因为一个模块可以有多个课程。如果tommorow使用集合、映射、链表或数据库映射器来实现对象,那么如果基于向量继承,就必须重写整个代码。别忘了,标准向量emplace(),push_back(),erase()。。。将需要过载,因为模块中课程的所有这些操作都需要调整课程持续时间
顺便说一句,类设计的一个很好的经验法则是为“is-a”关系使用继承,为“has-a”使用组合
更多支持和反对向量继承的论点如下
第二种选择看起来更好,因为课程、课程、模块实际上是一个命名实体。通过这种方法,对象之间的关系也更加清晰
这两种方法都符合利斯科夫替代原则:
- 如果为
编写代码,则可以使用相同的代码将命名实体替换为这些子类中的任何一个(前提是它们都实现了可以与基类使用的参数相同的构造函数)。无论您在未来对数据结构进行何种改进,这都是有意义的李>namedentity
- 如果您编写代码来处理
,则相同的代码可以用于向量
。但是,您可能会在构造函数中使用不同的语义。如果更改实现,LSP将适得其反李>课程
- 我建议不要继承自
。提供在包含的std::vector
上公开所需操作的方法。这使您既可以选择更改容器实现,也可以使用可能需要的任何类不变量向量
- 如果代码的任何其他部分只关心这些对象的名称,那么从
继承是一个好的设计namedentity
- 如果所有这些类都需要非纯抽象的
的功能,那么这是一个不同但也是有效的理由namedentity