类之间的关系
2015-09-18 17:45
260 查看
在类之间最常见的关系是
依赖(use-a)
聚合(has-a)也称为复合(composition)
继承(is-a)
表达类关系的UML连接图
在订单处理系统中:
order:订单
Item: 项目
Account:账户
又比如
(条款38)
public继承 意味着is-a,适用于base classes身上的每一件事情一定也适用于derived classes身上,因为每一个derived class对象也都是一个base class对象(条款32)
那么private继承呢?
如果classes之间的继承关系是private,那么编译器不会自动将一个derived class对象转换成一个base class对象,这和public继承不同,由private继承的所有成员,在derived class中会变成private属性。
private继承意味着根据某物实现出,如果D以private继承自B,意思是D对象根据B对象实现而得,其意义只及于软件实现层面,没有其他意义。
例如:
我们想要修改Widget class,让它记录每个成员函数被调用的次数,为了完成这项工作,我们需要设定某种定时器,让我们知道收集数据的时候是否到了。
现在有一个类:
如果我们让widget重新定义timer内的virtual函数,Widget必须继承自Timer,但是在这里public继承并不恰当,因为它们不是is-a的关系。
我们必须以private的形式继承Timer:
但是这样的设计并不是绝对必要的,我们可以用复合的方式取而代之。
这个设计同时涉及到public继承和复合,并且导入了一个新的class。
private继承主要用于一个意欲成为derived class者想访问一个意欲成为base class者的protected的成分,或者为了重新定义一个或多个virtual函数,这两个class之间是is-implemented-in-term-of 而非is-a 的关系。
还有一种情况,就是涉及到空间最优化时,可能会让你选择private 继承而不是继承加复合。
你会发现sizeof(HoldsAnInt)>sizeof(int)
可以确定sizeof(HoldsAnInt)==sizeof(int),这就是空白基类最优化(EBO),这对对象尺寸最小化的程序开发者而言可能很重要(条款39)
资料来源:
Java 核心技术卷 1
Effective C++
依赖(use-a)
聚合(has-a)也称为复合(composition)
继承(is-a)
表达类关系的UML连接图
在订单处理系统中:
order:订单
Item: 项目
Account:账户
依赖
order类使用Account类,因为必须访问Account对象查看信用状态,但是Item类不依赖于Account类。聚合(aggregation)或复合(composition)
比如,一个order对象包含一些Item对象又比如
class Address{...}; class PhoneNumber{...}; class Person{ public: ... private: std::string name; Address address; PhoneNumber voiceNumber; PhoneNumber faxNumber; }
(条款38)
继承(is-a)
比如RushOrder类继承自Order类,在RushOrder类中包含一些用于优先处理的特殊方法。public继承 意味着is-a,适用于base classes身上的每一件事情一定也适用于derived classes身上,因为每一个derived class对象也都是一个base class对象(条款32)
那么private继承呢?
如果classes之间的继承关系是private,那么编译器不会自动将一个derived class对象转换成一个base class对象,这和public继承不同,由private继承的所有成员,在derived class中会变成private属性。
private继承意味着根据某物实现出,如果D以private继承自B,意思是D对象根据B对象实现而得,其意义只及于软件实现层面,没有其他意义。
例如:
我们想要修改Widget class,让它记录每个成员函数被调用的次数,为了完成这项工作,我们需要设定某种定时器,让我们知道收集数据的时候是否到了。
现在有一个类:
class Timer{ public : explicit Timer(int tickFrequency); virtual void onTick() const; };
如果我们让widget重新定义timer内的virtual函数,Widget必须继承自Timer,但是在这里public继承并不恰当,因为它们不是is-a的关系。
我们必须以private的形式继承Timer:
class Widget: private Timer{ private: virtual void onTick() const; }
但是这样的设计并不是绝对必要的,我们可以用复合的方式取而代之。
class Widget{ private: class WidgetTimer: public Timer{ public: virtual void onTick() const; ... }; WidgetTimer timer; }
这个设计同时涉及到public继承和复合,并且导入了一个新的class。
private继承主要用于一个意欲成为derived class者想访问一个意欲成为base class者的protected的成分,或者为了重新定义一个或多个virtual函数,这两个class之间是is-implemented-in-term-of 而非is-a 的关系。
还有一种情况,就是涉及到空间最优化时,可能会让你选择private 继承而不是继承加复合。
class Empty{}; class HoldsAnInt{ private: int x; Empty e; }
你会发现sizeof(HoldsAnInt)>sizeof(int)
class HoldsAnInt:private Empty{ private: int x; }
可以确定sizeof(HoldsAnInt)==sizeof(int),这就是空白基类最优化(EBO),这对对象尺寸最小化的程序开发者而言可能很重要(条款39)
资料来源:
Java 核心技术卷 1
Effective C++
相关文章推荐
- C#txt文件读写基本操作
- 【笔记】PHP面向对象编程——高级实践(DAY 3)
- 检测当前进程是否存在硬件断点
- hdu 1800
- LaunchImage启动黑屏-模拟器可以,但是真机黑屏
- 随笔
- eclipse 开发python 小技巧分享
- opencv3.0.0的安装(Mac)与svm新变化
- 【转载】代码形式为reportviewer绑定数据源(1)
- 有道云笔记、印象笔记、为知笔记、麦库记事国内四大笔记软件全方面比较
- css3 appearance在iphone上面的问题
- 通过服务启动消息通知
- delphi的public 与 published
- UIView的autoresizingMask属性
- android - AsyncTask 异步操作
- 【CCF】ISBN号码
- UI:沙盒
- ie6 zoom css hack
- js数组之迭代器方法
- NSDate分类,把系统返回的时间与现在进行比较---秀清