390 likes | 544 Views
继 承(一). 继承的含义. 不同的类具有相似的特征 磁卡电话, IC 卡电话,手机,普通电话 麻雀,燕子,鸽子,大雁 分类. 鸟. 麻雀. 燕子. 鸽子. 大雁. 继承的含义. 由简单到复杂. 汽车. 小汽车. 卡车. 旅行车. 工具车. 小轿车. 面包车. 概念. 基类( base class ) 派生类( derived class ) 一个类可以既是基类,又是派生类. 继承的分类. 单继承和多继承. 汽车. 学生. 老师. 小汽车. 大汽车. 助教博士. 继承的定义. class base {
E N D
继承的含义 • 不同的类具有相似的特征 • 磁卡电话,IC卡电话,手机,普通电话 • 麻雀,燕子,鸽子,大雁 • 分类 鸟 麻雀 燕子 鸽子 大雁
继承的含义 • 由简单到复杂 汽车 小汽车 卡车 旅行车 工具车 小轿车 面包车
概念 • 基类(base class) • 派生类(derived class) • 一个类可以既是基类,又是派生类
继承的分类 • 单继承和多继承 汽车 学生 老师 小汽车 大汽车 助教博士
继承的定义 class base { int a; //私有成员 public: void setA(int a1); }; class derived : public base { int b; //私有成员 public : void setB(int b1); }; 派生类(子类) 基类(父类)
继承的方式 • public、protected和private 基类成员的访问控制 public 继承 protected 继承 private 继承 private private private private protected protected protected private public public protected private 基类成员在派生类中的访问控制
派生类 • 派生类也是类 • 可以有自己的数据成员和函数成员 • 派生类又是特殊的类 • 基类的所有成员也是派生类的成员 • 即:派生类继承了基类所有的成员
派生类成员的访问控制 • 派生类本身的成员 • 遵循通用的访问控制策略 • 派生类继承来的成员 • 派生类本身的函数成员可以访问基类的公有和保护成员 • 通过派生类对象只可以访问派生类和基类的公有成员
访问控制 class base { private: int a; protected: int b; public: void SetA(int a1) { a = a1; } void SetB(int b1) { b = b1; } };
访问控制 class derived : public base { private: int c; protected: int d; public: void SetC(int c1) { c = c1; } void SetD(int d1) { d = d1; } void Set_A(int a1) { a = a1; } // void Set_B(int b1) { b = b1; } // };
访问控制 base obj1; derived obj2; //可以通过派生类对象访问基类的公有成员 obj2.SetA(1); obj2.SetB(2); //可以直接访问派生类的公有成员 obj2.SetC(3); obj2.SetD(4);
protected的作用 • 封闭性和开放性的结合 • 不能被一般函数访问 • 能被派生类函数成员访问 • 为派生类提供了访问基类成员的特权
访问控制小结(public继承方式) 对派生类成员的可访问性 基类成员的 访问控制 对派生类对象的可访问性 在派生类中的访问控制 不可访问 不可访问 private private 可访问 不可访问 protected protected 可访问 可访问 public public
派生类对象的构造 • 派生类的构造函数中必须启动基类的构造函数(有缺省构造函数除外)
派生类的构造函数 class base { protected: int a; public: base(int a1) { a = a1;} //构造函数 };
派生类的构造函数 class derived : public base { int b; public: derived(int a1, int b1); }; derived :derived(int a1,int b1) : base(a1) { b = b1; }
构造函数的执行顺序 • 对象构造时 • 先执行基类的构造函数 • 再执行派生类的构造函数 derived dobj(2,3); 先执行:a = 2; 再执行:b = 3;
析构函数的调用顺序 • 析构时 • 先调用派生类的析构函数 • 再调用基类的析构函数
单继承举例 Disk name sides tracks sectors_per _track bytes_per_sector • 磁盘 FloppyDisk write_protect HardDisk controller_type
Disk类的定义 class Disk { public: Disk(char *nme int side, int track, int spt, int bps); long Capacity(); private: char name[64]; int sides; int tracks; int sector_per_track; int bytes_per_sector; };
FloppyDisk类的定义 class FloppyDisk : public Disk { public: FloppyDisk(char *name, int sides, int tracks, int spt, int bps, bool wp); void setWriteProtect( int state); private: bool write_protect; };
HardDisk类的定义 class HardDisk : public Disk{ public: HardDisk(char *name, int sides, int tracks, int spt, int bps, char * type); void set_controller_type(char *); private: char controller_type[64]; };
Disk类的实现 Disk::Disk(char *nme int side, int track, int spt, int bps) { name = nme; sides = side; tracks = track; sector_per_track = spt; byte_per_sector = bps; }
HardDisk类的实现 HardDisk:: HardDisk(char *name, int sides, int tracks, int spt, int bps, char * type): Disk(name, sides, tracks, spt, bps) { strcpy(controller_type, type); }
FloppyDisk类的实现 FloppyDisk::FloppyDisk(char *name, int sides, int tracks, int spt, int bps,bool wp) : Disk(name, sides, tracks, spt, bps) { write_protect = wp; }
多继承举例 填充类 填充颜色 填充图形 矩形类 长 宽 填充矩形类 填充矩形
Filled类的定义 class Filled { protected: int fillColor; int fillType; public: Filled(int filleColor, int fillType); void FillGraph(Scope scope); };
Rectangle类的定义 class Rectangle { protected: Point topLeft, bottomRight; int lineColor; public: Rectangle(Point top_left, Point bottom_right, int line_color); Rectangle(); long Area(); //求矩形面积 void Draw(); //绘制矩形 };
FilledRectangle类的定义 class FilledRectangle : public Filled, public Rectangle { private: GetScope(Scope & scope); public: FilledRectangle(Point top_left, Point bottom_right, int line_color); Draw(); //绘制填充矩形 };
FilledRectangle类的实现 void FilledRectangle::Draw() { Rectangle::Draw(); //调用基类的函数 Scope scope; GetScope(scope); //取矩形的范围 FillGraph(scope); //调用基类的函数 }
多级继承 电话 人员 无线电话 工作人员 有线电话 管理人员 脉冲电话 音频电话
Person类的定义 class Person { protected: char name[64]; int age; public: Person(char *name, int age); char * GetName(); int GetAge(); };
Worker类的定义 class Worker : public Person { protected: float wage; int workID; //工作证号 public: Worker(char *name, int age, float wage, int workID); void ChangeWage(int newWage); };
Worker类的实现 Worker::Worker(char *name, int age, float wage, int workID) : Person(name, age) { Worker::wage = wage; Worker::workID = workID; }
Manager类的定义 class Manager : public Worker { protected: int bonusLevel; //红利等级 char office[64]; //办公室 public: Manager(char *name, int age, float wage, int workID, int bonus_level, char * office); void ChangeOffice( char * new); };
Manager类的实现 Manager::Manager(char *name, int age, float wage, int workID, int bonus_level, char * office) : worker(name, age, wage, workID) { Manager::bonus_level = bonus_level; strcpy(Manager::office, office); }
小结 • 继承的含义 • 继承的分类 • 派生类成员的访问控制 • 构造函数和析构函数 • 继承举例
函数重载 • 派生类的成员函数可以重载基类的成员函数 FilledRectangle fr; fr.Draw(); //调用FillRectangle::Draw() fr.Rectangle::Draw(); //调用Rectangle::Draw() fr.Area(); //调用Rectangle::Area()