参考自《C++ Primer Plus 6th Edition》
除了修改代码外,有两种方法能够用来扩展类的定义,一个是组合,另一个就是继承
组合: 使用类型为别类的成员变量
继承: 从已有的类派生出新类,在新类中加入新的成员
本文仅讨论继承中的公有继承 (class derivedClass : public baseClass)
分为三部分: 第一部分讲述多态,第二部分讲述派生类的方法,第三部分讲一些额外补充的知识,比较杂
第一部分 多态
概念:
多态是针对类中的成员函数而言的。设有一个父类parent,和其子类(child1...childN)若干。设这些类中都定义了一个使用“多态机制”的成员函数A。这个成员函数A在每个类中,名称相同,参数列表(argument-list)也相同。如果我们为每个类都创建了一个对象,那么使用这些对象调用方法A,自然调用的都是对象所属类的那个A。那如果,声明父类parent的引用/指针,并且让这些引用/指针指向这些对象,再使用这些引用/指针来调用方法A呢? 答案还是一样,每个引用/指针会使用它所指的那个对象来调用方法A。
若方法A没有使用“多态机制”,那么引用/指针调用方法A会发生什么情况呢? 那么,它们都将调用,引用/指针的类型--parent类中的方法A。
以上情况可以推广: “如果没有使用多态,将根据引用/指针的类型来选择方法。如果使用了多态,将根据引用/指针指向的对象的类型来使用方法。”
优点:
前提: 需要创建子类 child1...childN的多个对象,并调用这些对象的A方法。
若不使用多态,那么创建这些对象后,你需要记住这每一个对象的名称,调用的时候,把这些名称,一个不落地写出,也就是说,记忆的任务交给了程序员。
若使用多态,你只需再创建对象后,把这些对象放到 类型为parent引用/指针的数组中,调用的时候,令数组元素访问方法A即可。即,可以使用一个数组来表示多种类型的对象。这就是多态性。
实现:
有两种方式可以实现 “多态公有继承”:
1. 在子类中重新定义父类的方法 ( 即override,函数名和参数列表均相同 )
2. 使用虚方法 ( 在子类和父类的那个要使用多态的方法名前加关键字 “virtual” )
更多:
我们知道,使用多态的时候,我们可以将对象赋给指针/引用。当使用指针/引用来访问多态方法时,程序会让所指向的那个对象调用它所在的类方法。但有时,所指向的那个对象的类型是不能在编译时确定的。因此,C++规定,当使用指针/引用来调用虚函数时,使用动态匹配(dynamic binding)。反之,使用静态匹配(static binding)。
举个简单的例子:
#include <iostream> using std::cin; using std::cout; class parent { public: virtual void print() { cout << "This is parent.\n"; } }; class child1 : public parent { public: void print() { cout << "This is child one.\n"; } }; class child2 : public parent { public: void print() { cout << "This is child two.\n"; } }; int main() { int choice; parent* p; cin >> choice; if(choice == 0) { parent obj; p = &obj; } else if (choice == 1) { child1 obj; p = &obj; } else { child2 obj; p = &obj; } p->print(); return 0; }