C++ Primer学习笔记(13)——封装、继承、多态
来源:互联网 发布:科目四考试软件 编辑:程序博客网 时间:2024/05/21 07:48
C++ 是一种典型的面向对象的编程语言,其最显著地特点是封装、继承和多态。充分理解封装、继承、多态是如何实现的,学好C++就不是难事了。
1.封装
封装是将多个细节元素组合在一起,隐藏起来,成为一个类。外部无法了解类内部是如何实现的,只需要考虑它的接口。
例如:将公司员工的姓名、年龄、工号等信息放在类的私有部分。
封装的好处:
避免类内部出现无意的、可能破坏对象状态的用户级错误。
随时间推移可以根据需求改变或缺陷报告来完善类实现,而无需改变用户级代码。
2.继承
该部分转自ruyue_ruyue的博客
什么是继承?
继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。其继承的过程,就是从一般到特殊的过程。
通过继承创建的新类称为“子类”或“派生类”。被继承的类称为“基类”、“父类”或“超类”。要实现继承,可以通过“继承”(Inheritance)和“组合”(Composition)来实现。在某些 OOP 语言中,一个子类可以继承多个基类。但是一般情况下,一个子类只能有一个基类,要实现多重继承,可以通过多级继承来实现。
继承的实现方式?
继承概念的实现方式有三类:实现继承、接口继承和可视继承。
1. 实现继承是指使用基类的属性和方法而无需额外编码的能力;
2. 接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力;
3. 可视继承是指子窗体(类)使用基窗体(类)的外观和实现代码的能力。
3. 多态
C++多态分为两种:静多态 和 动多态。静多态发生在编译期,动多态发生在运行期。
~ 静多态 ~
静多态可以通过模板和函数重载来实现(之所以说c++中的多态,主要还是因为模板这个东西)
1)函数模板
template T max(const T& lsh, const T& rsh){ return (lsh > rsh) ? lsh : rsh;}
这是一个模板,返回任意类型对象的最大值,前提是该类型能够使用 > 运算符进行比较,并且返回值是bool 型。
模板的使用:
int a = 2, b = 3;cout << max(a, b) << endl; float c = 2.0 , d = 3.0;cout << max(c, d) << endl;
输出结果为:
33.0
由于模板的实例化发生在编译期,故上述绑定是发生在编译期的,即在编译时编译器发现你调用 max(a, b)时自动生成如下函数(将模板中的 T 全部用 int 替换):
int max(const int& lsh, const int& rsh){ return (lsh > rsh) ? lsh:rsh;}
同样地,当编译器发现你调用 max(c, d) 时,自动将模板中的 T 用 float 替换了。
2)函数重载
如果两个函数名相同,其参数类型或参数个数不完全相同,则成为函数重载。函数调用的时候,根据实参的类型和个数确定调用哪个函数。
(如果两个函数是同一个函数,必须是其函数名、参数类型、参数个数、函数体完全相同。)
举个例子:
int max (int a , int b){ // 函数1 return (a > b) ? a:b; }int max (int a , int b , int c){ // 函数2 return max(max(a,b),c); }float max (float a ,float b){ // 函数3 return (a > b) ? a:b;}
使用:
int a = 2, b = 3, c = 4;float a1 = 2.0 , b1 = 3.0;cout << max(a,b) << endl; // 函数1cout << max(a,b,c) <<endl; // 函数2cout << max(a1,b1) <<endl; // 函数3
输出结果为:
343.0
确定具体调用哪个函数的过程也发生在编译期。max(a,b) ,编译器发现只有两个int 类型的参数,就调用函数1 ;max(a,b,c) ,有三个int 型参数,调用函数2;max(a1,b1),有两个float 型参数,于是调用函数3。该过程称作函数匹配。
~ 动多态 ~
动多态是通过继承、虚函数(virtual)、指针来实现的,关键是虚函数的使用。关于虚函数的实现机制,是C++面试中几乎总会被问到的,具体实现机制我将在下一篇文章中详细阐述。
下面讲述多态的实现:
class A {public: virtual void func() const { cout << "A :: func()" << endl; }};class B : public A {public: virtual void func() const { cout << "B :: func()" << endl; }};
使用:
A *a = B(); // 定义 A 类型的指针,指向 B 对象A -> func(); // 指针 A 指向func()函数
在编译期是不调用任何函数的,编译器编译到 a->func()时只是检查有没有语法错误,并不知道调用的是 A 类还是 B 类的 func() , 由于 a 是一个指向 B 对象的指针,所以a 只知道它指向的是一个 A 类型(或者能转换成A类型)的对象。由于是公有继承,说明B是一种A。
在运行期,a 要调用a所指向对象的 func() 函数,就对它指向的对象下达调用func() 的命令,结果a 所指向的是一个 B 对象,所以就调用了B类型的func()函数,所以输出地是 B::func()。
总结:
在编译期的行为是静多态,有模板和函数重载;
在运行期的行为是动多态,通过虚函数来实现。
- C++ Primer学习笔记(13)——封装、继承、多态
- Java学习笔记(二)——封装、继承、多态
- 【学习笔记】C++primer plus 13.继承
- 黑马程序员—Objective-C学习—封装、继承、多态
- C++ Primer学习笔记 — 复制控制与继承
- C++Primer学习笔记—(const限定符)
- 学习笔记(C++primer)
- Object-C详细编程(二)—封装,继承,多态
- 【C#学习】——封装、继承、多态
- C#学习笔记(5)----- 封装、继承、多态
- C#学习笔记(5)----- 封装、继承、多态
- C#学习笔记(5)----- 封装、继承、多态
- 黑马程序员--IOS学习笔记(封装、继承、多态)
- java 入门学习笔记(封装,继承,多态)
- python学习笔记14(多态、封装、继承)
- Java学习笔记(一)----封装 继承 多态 抽象 接口
- JAVA学习笔记04封装,继承,多态
- Javascript学习笔记九——prototype封装继承
- Python 3面向对象编程
- 读书笔记----深入理解计算机系统
- TCP/IP、Http、Socket的区别
- 网页中图片预加载的原理
- 生成模型和判别模型
- C++ Primer学习笔记(13)——封装、继承、多态
- MYSQL游标嵌套循环 动态游标
- SVM分类task1
- awk
- Block 好好运用
- 【Java】实现一个算法,找出一个单链表中倒数第K个结点
- 马氏距离的几张截图
- 堆、栈的区别
- 【Rayeager PX2】PX2上使用GPIO口的例程