面向对象程序设计的核心思想是:数据抽象、继承和动态绑定。
数据抽象:将类的接口与实现分离;
继承:定义相似类型并对相似关系建模;
动态绑定:一定程度上上忽略相似类型间的区别,用统一方式使用它们。
继承
通过继承联系在一起的类构成层次关系。层次关系的最底层或者说根部的类叫做基类,直接或者间接从基类继承而来得到的类叫做派生类。
基类负责定义整个层次共有的特性,派生类在基类的基础上根据自身需求进行扩展。
在面向对象程序设计的继承中,基类将需要进行扩展的函数与原封不动直接继承的函数进行区分对待。需要进行自定义扩展的函数,基类将其声明为虚函数。
派生类通过类派生列表来指出从哪个基类进行继承。类派生列表的形式是:类名后一个分号,后面紧跟以逗号分割的基类列表。每个基类前可以有访问说明符,对class来说,如果省略,则默认private继承。
class derived: public base // 以public方式继承base { public: ... };
对于public继承得到的派生类,完全可以将其视为基类对象来使用。
对于在基类中被声明为虚函数的成员函数,在派生类中,若需要根据自身需要对该成员函数进行重新定义,则必须在派生类内部重新声明一次该虚函数。重新声明时,可以省略关键词virtual
动态绑定
通过动态绑定的特性,可以用一段相同代码同时处理基类和派生类的对象。要使用动态绑定,则处理代码的形参必须是对基类对象的引用类型或指针类型。
例如,有如下代码:
1 #include <iostream> 2 3 using std::cout; 4 using std::endl; 5 using std::string; 6 7 class Quote 8 { 9 public: 10 string isbn() const; 11 virtual double net_price(size_t) const; 12 }; 13 14 string Quote::isbn() const 15 { 16 return "abc"; 17 } 18 19 double Quote::net_price(size_t n) const 20 { 21 return 3.14; 22 } 23 24 class Bulk_quote:public Quote 25 { 26 public: 27 double net_price(size_t ) const; 28 }; 29 30 double Bulk_quote::net_price(size_t n) const 31 { 32 return 6.28; 33 } 34 35 double print_total(std::ostream &os, Quote &item, size_t n) 36 { 37 double ret = item.net_price(n); 38 os << "ISBN: " << item.isbn() << " # sold: " << n << " total due: " << ret << endl; 39 return ret; 40 } 41 42 int main(int argc, char const *argv[]) 43 { 44 Quote basic; 45 Bulk_quote bulk; 46 print_total(cout, basic, 20); 47 print_total(cout, bulk, 30); 48 return 0; 49 }