目录与子目录的面向对象关系判定:组合还是继承?
目录与子目录的面向对象关系判定:组合还是继承?
先咱们回顾下你提到的面向对象里的两种核心对象关系:
- 继承(is-a 关系):比如文本文件、位图文件都是文件,所以它们继承自
File类,能复用父类的GetFileSize()方法,这是典型的"是一个"的关系。 - 组合(has-a 关系/也叫包含):比如目录包含文件,所以
Directory类里持有一个std::list<File>的成员,这是"拥有一个"的关系。
a) 目录与子目录的关系是什么?
其实目录和子目录本质上是同一种事物——它们都具备目录的核心特性:能包含文件、能包含其他目录、有路径信息、能被遍历等等。从面向对象的角度看,子目录完全符合is-a的判定:它"是一个"目录,只是在文件系统层级里被另一个目录包含而已。
b) 既然目录包含子目录,那它肯定是组合?这个理解对吗?
你的思路只对了一半!咱们得拆成两个维度来看:
- 从"包含行为"的维度:目录和子目录之间确实存在组合关系——因为一个目录可以"拥有"多个子目录,就像它拥有多个文件一样。你可以在
Directory类里添加一个成员来持有子目录,这就是组合的体现。 - 从"本质属性"的维度:子目录本身就是目录的一种,完全不需要单独定义一个
SubDirectory类。它和父目录的区别只是所处的层级不同,核心功能和属性是完全一致的,这其实是继承关系的一种特殊情况——但这里不需要显式继承,因为子目录就是Directory类的实例本身。
给你写个代码示例就一目了然了:
#include <list> #include <string> class File { public: void GetFileSize() { /* 实现逻辑 */ } }; class Directory { private: std::string dir_path; std::list<File> contained_files; std::list<Directory> contained_subdirs; // 用组合实现"包含子目录" public: void add_file(const File& file) { contained_files.push_back(file); } void add_subdirectory(const Directory& sub_dir) { contained_subdirs.push_back(sub_dir); } void calculate_total_size() { // 可以递归计算自身文件大小 + 所有子目录的总大小 // 这里可以复用逻辑,因为子目录也是Directory对象 } };
你看,这里没有单独的SubDirectory类,因为子目录就是Directory的实例,同时Directory通过组合的方式持有其他Directory对象,完美贴合真实的文件系统逻辑——既满足了"目录包含子目录"的has-a关系,又符合"子目录是目录"的is-a关系。
备注:内容来源于stack exchange,提问作者Gajanana D S
相关产品推荐
相关产品推荐

