什么是动态绑定,什么是多态?
发送给对象的请求与它相应的操作在运行时刻的连接就称之为动态绑定(dynamic binding)
动态绑定允许在运行时刻彼此替换有相同类型(接口)的对象,这种可替换性就称为多态(polymorphism)
抽象类,具体类,混入类
抽象类的主要目的是为其子类定义公共接口,抽象类不能实例化,抽象类中定义但没实现的操作是抽象操作
非抽象类被称为具体类
混入类类似抽象类,提供可选择的接口,但是它的使用需要多继承
类继承,接口继承
类继承根据一个对象的实现定义了另一个对象的实现,它是代码和表示的共享机制
接口继承描述了一个对象什么时候可以被用来替换另一个对象
C++中,接口继承的标准方法是公有继承一个含有(纯)虚成员函数的类,纯接口继承接近于公有继承于纯抽象类,纯实现继承(纯类继承)接近于私有继承
对接口编程,而不是对实现编程
类继承能进行实现的复用,然这还不够,这不能提供多态,我们需要通过接口继承来实现多态
不将变量声明为某个特定的具体类的实例变量,而是让它遵从抽象类所定义的接口,这是设计模式的一个常见主题
复用机制
OO系统中功能复用的最常用技术是类继承和对象组合
在继承方式中,父类的细节对子类可见,所以类继承复用机制通常被称为白箱复用
新的功能也可以通过组合对象或组装对象来实现,因为对象的内部细节是不可见的,所以这种复用风格被称为黑箱复用
两种复用机制的优缺点
类继承:
优点:类继承在编译时刻静态定义,可以直接使用,程序设计语言直接支持类继承;类继承可以很方便的改变被复用的功能
缺点:类继承在编译时刻确定,无法在运行时改变从父类继承的实现;继承破坏了封装性,因为它对子类揭示了父类的实现细节;父子类之间的依赖关系很紧密,父类的变化必然会导致子类发生变化
对象组合:
优点:对象组合通过对其他对象的引用而在运行时刻动态定义,运行时刻可以用类型相同的一个对象来替代另一个对象;对象通过接口访问,所以不破坏封装性,并且实现上不存在依赖关系;有助于保持每个类被封装并被集中在单个任务上,这有助于限制类和类继承层次的规模
缺点:有间接性,比较低效
优先使用对象组合,而不是类继承
有关委托
委托是一种对象组合方式,有两个对象参与处理一个请求,接受请求的对象将操作委托给它的代理者
委托是对象组合的特例,可以用来说明对象组合可以作为一个代码复用机制来替代继承
有些模式使用了委托
参数类型化(模板)
参数类型化是除继承和对象组合方式外的第三种方法来组合OO系统中的行为;它是一种功能复用技术,从某种角度上讲也是一种代码复用技术,通过继承和组合方式的复用也包括了功能复用和代码复用
OO程序的运行时结构和代码结构
代码结构是在编译时刻确定的,它由继承关系固定的类组成
程序的运行时结构是由快速变化的通信对象网络组成
两个结构是彼此独立的,代码不可能揭示系统如何工作的全部
设计应该支持变化
获得最大限度的复用的关键是预见到变化,必须考虑系统在其生命周期内会发生怎么样的变化
设计模式能确保系统能以特定方式变化,从而帮助我们避免重新设计系统,也就是说能让系统具有对变化的健壮性
设计模式能应用在应用程序、工具箱(代码复用)、框架(设计复用)的设计与编写中
设计模式与框架的区别
1 设计模式比框架更加抽象:框架能用代码表示,而设计模式只有其实例才能表示为代码,框架可以被直接执行和复用,而设计模式的每一次复用都需要通过代码实现一遍,给予这个区别,我们可以把设计模式当成是一种思想复用
2 设计模式是比框架更小的体系结构元素:一个框架可能包含了多个设计模式
3 框架比设计模式更特例化:框架针对于一个特定的应用领域,而设计模式几乎可能被用于任何应用
框架的作用
框架是OO系统获得最大复用的方式,大的OO应用将会由多层彼此合作的框架组成,应用的大部分设计和代码讲来源于它所使用的框架,框架正变得越来越重要,学习设计模式,可以降低框架学习的难度