OOP07:Polymorphism 多态
第7章 Polymorphism 多态
7.1 类型转换 Conversions
(1)public继承,应该包含替换:即将子类转成父类(子类是父类的超集)
(a)如果B是A的子类,那么能使用A的地方,一定能使用B
(b)如果B是A的子类,那么对A成立的,对B也成立
class A{ |
7.1.1 向上转换 Upcast
Manager pete("Pete", "444-55-6666", "Bakey"); |
例:drawing
1 具体对象、共有数据、接口
2 继承结构
在父类Shape中,定义了接口render()
在子类中,通过多态的机制,重定义接口render()
3 类的声明
class XYPos{ ... }; // x,y point |
7.2 多态 Polymorphism
向上转换upcast:将子类的对象作为父类的一个对象
多态使用的时间:upcast
多态的目的:在upcast的时候,使用子类的对象
动态绑定binding:
绑定binding:调用哪个函数
静态绑定static binding:调用函数作为代码
动态绑定dynamic binding:调用对象的函数
7.2.1 non-virtual function
(1)视为静态绑定,编译时就确定好使用哪个函数
(2)调用较快
7.2.2 virtual function
- 子类一定要重定义该函数
- 对象存储了虚函数的信息
- 编译器会检查、并动态调用正确的函数
- 编译器优化:如果编译器在编译的时候知道应该调用哪个函数,则会生成一个静态调用
class Ellipse : public Shape { |
7.3 抽象基础类 Abstract base classes
7.3.1 定义
- 一个抽象的基础类有纯虚函数pure virtual functions
- 只定义返回值、参数
- 不需要给函数体
- 抽象基础类不能直接实例化≠不能用指针
必须由一个子类继承
子类必须要实现抽象类的所有纯虚函数
7.3.2 例:定义纯虚函数
class XYPos{ ... }; // x,y point |
7.3.3 作用
(1)便于建模 ==> 抽象定义
(2)强制要求正确的行为 ==> 所有子类都必须有该行为
(3)定义接口,而不是定义实现
7.3.4 例:定义抽象类
class CDevice { |
(1)所有非静态的成员函数都是纯虚函数,除了析构函数
(2)虚拟析构函数,没有函数体
(3)没有非静态的成员变量,可以有静态成员变量
7.4 Virtual的实现机制
(1)在内存中,会存储一个指针,指向当前类的虚函数表
(2)一个class会有一个虚函数表
(3)父类的变量会在子类的变量之前
(4)子类的虚函数表中,不会有父类的虚函数表,因为子类已经将所有虚函数重新定义了
7.5 赋值与upcast
Ellipse elly(20f,40f); |
7.6 Relaxation
虚函数的返回类型为指针、引用的时候,子类可以修改返回类型
虚函数的返回类型为class的时候,子类不能修改返回类型
class Expr{ |
7.7 Overloading and virtuals
重载的几个函数,都需要被子类重定义
class Bass{ |
7.8 注意
(1)不要重新定义non-virtual的函数
(2)不要重定义继承函数的缺省值
class A { |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 华风夏韵!
评论