C++的三大特性封装、继承和多态

 

封装可使得代码模块化,继承能够扩展已存在的代码,他们的目的都是为了代码重用。而多态的目的则是为了接口重用ios

  • 封装:封装是在设计类的一个基本原理,是将抽象获得的数据和行为(或功能)相结合,造成一个有机的总体,也就是将数据与对数据进行的操做进行有机的结合,造成“类”,其中数据和函数都是类的成员。c++

  • 继承:若是一个类别B“继承自”另外一个类别A,就把这个B称为“A的子类”,而把A称为“B的父类别”也能够称“A是B的超类”。继承可使得子类具备父类别的各类属性和方法,而不须要再次编写相同的代码。在令子类别继承父类别的同时,能够从新定义某些属性,并重写某些方法,即覆盖父类别的原有属性和方法,使其得到与父类别不一样的功能。编程

    1. 访问权限模块化

      • public: 父类对象内部、父类对象外部、子类对象内部、子类对象外部均可以访问。
      • protected:父类对象内部、子类对象内部能够访问,父类对象外部、子类对象外部都不可访问。
      • private:父类对象内部能够访问,其余都不能够访问。

      |访问对象|public|protected|private|
      |-|-|-|-|
      |父类|可见|可见|可见|
      |子类|可见|可见|不可见|
      |父类外部|可见|不可见|不可见|
      |子类外部|可见|不可见|不可见|函数

    2. 继承方式
      ps.三种继承方式不影响子类对父类的访问权限,子类对父类只看父类的访问控制权。继承方式是为了控制子类(也称派生类)的调用方(也叫用户)对父类(也称基类)的访问权限。public、protected、private三种继承方式,至关于把父类的public访问权限在子类中变成了对应的权限。 如protected继承,把父类中的public成员在本类中变成了protected的访问控制权限;private继承,把父类的public成员和protected成员在本类中变成了private访问控制权。优化

      ps.友元是类级别的,不存在继承的问题。设计

  • 多态:多态性能够简单地归纳为“一个接口,多种方法”,程序在运行时才决定调用的函数,它是面向对象编程领域的核心概念。多态(polymorphism),字面意思多种形状。指针

    1. 静态多态:静态多态也称为静态绑定或早绑定。编译器在编译期间完成的,编译器根据函数实参的类型(可能会进行隐式类型转换),可推断出要调用那个函数,若是有对应的函数就调用该函数,不然出现编译错误。调试

      • 函数重载code

        编译器根据函数不一样的参数表,对同名函数的名称作修饰,而后这些同名函数就成了不一样的函数(至少对于编译器来讲是这样的)。函数的调用,在编译器间就已经肯定了,是静态的。也就是说,它们的地址在编译期就绑定了(早绑定)。

      • 泛型编程

        泛型编程就是指编写独立于特定类型的代码,泛型在C++中的主要实现为模板函数和模板类。
        泛型的特性:

        1. 函数模板并非真正的函数,它只是C++编译生成具体函数的一个模子。
          1. 函数模板自己并不生成函数,实际生成的函数是替换函数模板的那个函数,好比上例中的add(sum1,sum2),这种替换是编译期就绑定的。
          3. 函数模板不是只编译一份知足多重须要,而是为每一种替换它的函数编译一份。
          4. 函数模板不容许自动类型转换。
          5. 函数模板不能够设置默认模板实参。好比template <typename T=0>不能够。
    2. 动态多态
      c++的动态多态是基于虚函数的。对于相关的对象类型,肯定它们之间的一个共同功能集,而后在基类中,把这些共同的功能声明为多个公共的虚函数接口。各个子类重写这些虚函数,以完成具体的功能。客户端的代码(操做函数)经过指向基类的引用或指针来操做这些对象,对虚函数的调用会自动绑定到实际提供的子类对象上去。

    3. 宏多态(?)
      带变量的宏能够实现一种初级形式的静态多态:

      #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";
      }
    4. 动态多态和静态多态的比较

      1. 静态多态
        • 优势:
          1. 因为静多态是在编译期完成的,所以效率较高,编译器也能够进行优化;
          2. 有很强的适配性和松耦合性,好比能够经过偏特化、全特化来处理特殊类型;
          3. 最重要一点是静态多态经过模板编程为C++带来了泛型设计的概念,好比强大的STL库。
        • 缺点:
          1. 因为是模板来实现静态多态,所以模板的不足也就是静多态的劣势,好比调试困难、编译耗时、代码膨胀、编译器支持的兼容性不可以处理异质对象集合
      2. 动态多态
        • 优势:
          1. OO设计,对是客观世界的直觉认识;
          2. 实现与接口分离,可复用
          3. 处理同一继承体系下异质对象集合的强大威力
        • 缺点:
          1. 运行期绑定,致使必定程度的运行时开销;
          2. 编译器没法对虚函数进行优化
          3. 笨重的类继承体系,对接口的修改影响整个类层次;
      3. 不一样点:
        • 本质不一样,迟早绑定。静态多态在编译期决定,由模板具现完成,而动态多态在运行期决定,由继承、虚函数实现;
        • 动态多态中接口是显式的,以函数签名为中心,多态经过虚函数在运行期实现,静态多台中接口是隐式的,以有效表达式为中心,多态经过模板具如今编译期完成
      4. 相同点:
        • 都可以实现多态性,静态多态/编译期多态、动态多态/运行期多态;
        • 都可以使接口和实现相分离,一个是模板定义接口,类型参数定义实现,一个是基类虚函数定义接口,继承类负责实现;
相关文章
相关标签/搜索