封装可使得代码模块化,继承能够扩展已存在的代码,他们的目的都是为了代码重用。而多态的目的则是为了接口重用ios
封装:封装是在设计类的一个基本原理,是将抽象获得的数据和行为(或功能)相结合,造成一个有机的总体,也就是将数据与对数据进行的操做进行有机的结合,造成“类”,其中数据和函数都是类的成员。c++
继承:若是一个类别B“继承自”另外一个类别A,就把这个B称为“A的子类”,而把A称为“B的父类别”也能够称“A是B的超类”。继承可使得子类具备父类别的各类属性和方法,而不须要再次编写相同的代码。在令子类别继承父类别的同时,能够从新定义某些属性,并重写某些方法,即覆盖父类别的原有属性和方法,使其得到与父类别不一样的功能。编程
访问权限模块化
|访问对象|public|protected|private|
|-|-|-|-|
|父类|可见|可见|可见|
|子类|可见|可见|不可见|
|父类外部|可见|不可见|不可见|
|子类外部|可见|不可见|不可见|函数
继承方式
ps.三种继承方式不影响子类对父类的访问权限,子类对父类只看父类的访问控制权。继承方式是为了控制子类(也称派生类)的调用方(也叫用户)对父类(也称基类)的访问权限。public、protected、private三种继承方式,至关于把父类的public访问权限在子类中变成了对应的权限。 如protected继承,把父类中的public成员在本类中变成了protected的访问控制权限;private继承,把父类的public成员和protected成员在本类中变成了private访问控制权。优化
ps.友元是类级别的,不存在继承的问题。设计
多态:多态性能够简单地归纳为“一个接口,多种方法”,程序在运行时才决定调用的函数,它是面向对象编程领域的核心概念。多态(polymorphism),字面意思多种形状。指针
静态多态:静态多态也称为静态绑定或早绑定。编译器在编译期间完成的,编译器根据函数实参的类型(可能会进行隐式类型转换),可推断出要调用那个函数,若是有对应的函数就调用该函数,不然出现编译错误。调试
函数重载code
编译器根据函数不一样的参数表,对同名函数的名称作修饰,而后这些同名函数就成了不一样的函数(至少对于编译器来讲是这样的)。函数的调用,在编译器间就已经肯定了,是静态的。也就是说,它们的地址在编译期就绑定了(早绑定)。
泛型编程
泛型编程就是指编写独立于特定类型的代码,泛型在C++中的主要实现为模板函数和模板类。
泛型的特性:
1. 函数模板并非真正的函数,它只是C++编译生成具体函数的一个模子。 1. 函数模板自己并不生成函数,实际生成的函数是替换函数模板的那个函数,好比上例中的add(sum1,sum2),这种替换是编译期就绑定的。 3. 函数模板不是只编译一份知足多重须要,而是为每一种替换它的函数编译一份。 4. 函数模板不容许自动类型转换。 5. 函数模板不能够设置默认模板实参。好比template <typename T=0>不能够。
动态多态
c++的动态多态是基于虚函数的。对于相关的对象类型,肯定它们之间的一个共同功能集,而后在基类中,把这些共同的功能声明为多个公共的虚函数接口。各个子类重写这些虚函数,以完成具体的功能。客户端的代码(操做函数)经过指向基类的引用或指针来操做这些对象,对虚函数的调用会自动绑定到实际提供的子类对象上去。
宏多态(?)
带变量的宏能够实现一种初级形式的静态多态:
#include <iostream> #include <string> // 定义泛化记号:宏ADD #define ADD(A, B) (A) + (B); int main() { int i1(1), i2(2); std::string s1("Hello, "), s2("world!"); int i = ADD(i1, i2); // 两个整数相加 std::string s = ADD(s1, s2); // 两个字符串“相加” std::cout << "i = " << i << "/n"; std::cout << "s = " << s << "/n"; }
动态多态和静态多态的比较
迟早绑定
。静态多态在编译期决定,由模板具现完成,而动态多态在运行期决定,由继承、虚函数实现;函数签名
为中心,多态经过虚函数在运行期实现,静态多台中接口是隐式的,以有效表达式
为中心,多态经过模板具如今编译期完成