1 继承的基本概念 通过一种机制表达类型之间的共性和特性的方式,利用已有的数据类型定义新的数据类型,这种机制称为继承。 eg: 人类:姓名、年龄、吃饭、睡觉 学生类:姓名、年龄、学号、吃饭、睡觉、学习 教师类:姓名、年龄、工资、吃饭、睡觉、授课 人类:姓名、年龄、吃饭、睡觉 学生类继承人类:学号、学习 教师类继承人类:工资、授课 人类(基类/父类) / \ 学生类 教师类(派生类/子类) 基类派生子类,子类继承基类 2 继承语法 class 子类:继承方式1 基类1,继承方式2 基类2...{ ... }; 继承方式:public、protected、private eg: class Human{ public: int age; string name; }; class Student:public Human{ //Student继承了Human类 //Student类存在一份Human类中的成员 }; 3 继承的特性(public) 3.1 向上造型(重点掌握) 将子类类型的指针或引用转换为基类类型的指针或引用。这种操作性缩小的类型转换,在编译器看来是安全的,因此可以隐式完成。 3.2 向下造型: 将基类类型的指针或引用转换为子类类型的指针或引用。这种操作性扩大的类型转换,在编译器看来是危险的,因此必须显示的完成。 用一个人,学生,教师类来说吧 1 #include <iostream> 2 using namespace std; 3 4 class Human{ 5 public: 6 Human(const string &name,int age): 7 m_name(name),m_age(age),m_id(100){} 8 void eat(const string &food)const{ 9 cout << "我在吃" << food << endl; 10 } 11 void sleep(int time)const{ 12 cout << "我睡了" << time << "小时." << endl; 13 } 14 protected: //保护类型成员可以在类的内部和子类中访问 15 string m_name; 16 int m_age; 17 //私有成员子类无法直接访问,但可以共有或保护的 18 //接口函数来间接访问 19 const int &get_id(void)const{ 20 return m_id; 21 } 22 private: 23 int m_id; 24 }; 25 //学生类,继承人类 26 class Student:public Human{ 27 public: 28 //基类子对象:子类对象包含基类中的那部分成员 29 //通过初始化表显示指名基类子对象的初始化方式 30 Student(const string &name,int age,int no): 31 Human(name,age),m_no(no){} 32 void who(void)const{ 33 cout << "我叫" << m_name << "今年" << m_age << 34 "岁,学号是" << m_no << endl; 35 36 } 37 void learn(const string &course)const{ 38 cout << "我在学" << course << endl; 39 } 40 private: 41 int m_no; 42 43 }; 44 //教师类,继承子类 45 class Teacher:public Human{ 46 public: 47 Teacher(const string &name,int age,double salary): 48 Human(name,age),m_salary(salary){} 49 void who(void){ 50 cout << "我叫" << m_name << "今年" << m_age 51 << "岁,每月的薪水为:" << m_salary << endl; 52 } 53 void teach(const string &course)const{ 54 cout << "我在教" << course << endl; 55 } 56 private: 57 double m_salary; 58 }; 59 int main(void){ 60 Student s("悟空",30,10011); 61 s.who(); 62 s.eat("芒果"); 63 s.sleep(8); 64 s.learn("念经"); 65 Teacher t("三藏",35,1000); 66 t.who(); 67 t.sleep(6); 68 t.teach("佛法"); 69 70 //向上造型,安全,可以隐式转换 71 //ph:指向子类对象的基类指针 72 Human *ph = &s; //缩小操作范围,可以 73 ph->eat("桃子"); 74 ph->sleep(10); 75 //ph->who() 这句出错,已经转换为基类型了,无法操作子类 76 77 //安全的向下造型,必须显示完成 78 Student *ps = static_cast<Student *>(ph); //扩大操作范围,安全 79 ps->who(); 80 81 //危险的向下造型 //因为不知道那个内存空间大于基类的空间存的什么内容 82 Human h("张飞",28); 83 ps = static_cast<Student *>(&h); //扩大操作范围,危险 84 ps->who(); 85 return 0; 86 } tarena@ubuntu:~/cplus/day08$ g++ 02inheritance.cpp tarena@ubuntu:~/cplus/day08$ ./a.out 我叫悟空今年30岁,学号是10011 我在吃芒果 我睡了8小时. 我在学念经 我叫三藏今年35岁,每月的薪水为:1000 我睡了6小时. 我在教佛法 我在吃桃子 我睡了10小时. 我叫悟空今年30岁,学号是10011 我叫张飞今年28岁,学号是18407464 |
|