问题引出
如果子类定义了与父类中原型相同的函数会发生什么?
函数重写:在子类中定义与父类中原型相同的函数,函数重写只发生在父类与子类之间
父类中被重写的函数依然会继承给子类
默认情况下子类中重写的函数将隐藏父类中的函数
通过作用域分辨符::可以访问到父类中被隐藏的函数
C/C++是静态编译型语言:在编译时,编译器自动根据指针的类型判断指向的是一个什么样的对象
1、在编译此函数的时,编译器不可能知道指针 p 究竟指向了什么。
2、编译器没有理由报错。
3、于是,编译器认为最安全的做法是编译到父类的print函数,因为父类和子类肯定都有相同的print函数。
面向对象新需求
如果我传一个父类对象,执行父类的print函数
如果我传一个子类对象,执行子类的printf函数
现象产生的原因
赋值兼容性原则遇上函数重写出现的一个现象
没有理由报错
对被调用函数来讲,在编译器编译期间,我就确定了,这个函数的参数是p,是Parent类型的。。。
静态链编
解决方案
C++中通过virtual关键字对多态进行支持
使用virtual声明的函数被重写后即可展现多态特性
多态实例
1 |
|
多态的工程意义
面向对象3大概念
封装:突破了C语言函数的概念。。
继承:代码复用 。。。。我复用原来写好的代码。。。
多态:多态可以使用未来,写了一个框架,可以调用后来人,写的代码的能力
多态成立的条件
间接赋值成立的3个条件
1 定义两个变量。。。
2 建立关联 。。。。
3 *p
多态成立的三个条件
1 要有继承
2 要有函数重写(虚函数)
3 要有父类指针(父类引用)指向子类对象
多态是设计模式的基础,多态是框架的基础
多态的理论基础
静态联编和动态联编
联编是指一个程序模块、代码之间互相关联的过程。
静态联编(static binding),是程序的匹配、连接在编译阶段实现,也称为早期匹配。
重载函数使用静态联编。
动态联编是指程序联编推迟到运行时进行,所以又称为晚期联编(迟绑定)。
switch 语句和 if 语句是动态联编的例子。
C++与C相同,是静态编译型语言
在编译时,编译器自动根据指针的类型判断指向的是一个什么样的对象;所以编译器认为父类指针指向的是父类对象。
由于程序没有运行,所以不可能知道父类指针指向的具体是父类对象还是子类对象,从程序安全的角度,编译器假设父类指针只指向父类对象,因此编译的结果为调用父类的成员函数。这种特性就是静态联编。