<font size="5"><center>继承与派生</center></font>
<font color="#FF0066">说明:以下实验证明一个是出自以Person类为父类,Student为子类的源代码,另一个出自以Point为父类,Recetangle为子类的源代码</font>
派生类生成过程
1.吸收基类成员</br> 2.改造基类成员 </br> 3.添加新成员</br>
过程三步骤详述
-
吸收基类成员</br> 派生过程中构造函数和析构函数都不被继承,因此在对派生类新增成员进行初始化,需要在派生类写构造函数负责对新增成员的初始化,而从基类继承的成员,依旧由基类的构造函数完成
-
改造基类成员<br/> (1)基类成员的访问问题,靠继承方式控制<br/> (2)对基类数据或函数成员的覆盖和隐藏,如果派生类声明了一个和某个基类成员同名的新成员<font color="#FF0066">(注:函数要参数相同,如果不同的话,就是函数重载)</font>,派生的新成员会隐藏基类中同名的函数,并且在类外通过生成对象来直接使用成员名时,基类的成员就会被隐藏,即同名隐藏<br/>
<font color="#FF0066">同名隐藏<br/>

同名隐藏前:<br/> 
同名隐藏后:<br/></font> 
- 添加新成员<br/> 通过派生类中新成员派生类新功能的实现:<br/>
<font color="#FF0066">Person类中的成员函数:<br/></font> 
<font color="#FF0066">Student类中的成员函数:<br/></font> 
访问控制
- 继承语法:<br/> Class 派生类名:继承方式(public private protected) 基类名{}<br/>
- 分类:<br/> (1)公有继承:(常用)<br/> 当类的继承方式是公有继承,即public时,父类中public和protected中的成员访问属性不变,而父类private中的成员在子类中不能直接访问,可通过从父类中继承的公共接口对此进行操作<br/>
<font color="#FF0066">私有成员报错<br/></font> 
<font color="#FF0066">公有和保护成员不报错<br/></font> 
(2)私有继承:(不常用)<br/> 当类的继承方式是私有继承,即private时,父类的公有成员和保护成员以私有成员的身份出现在子类中,在子类内部可以互相互访问,但在类外通过对象就不能访问和操作,而父类private中的成员在子类中还是子类外都不能直接访问经过私有继承后,父类中的成员成为子类私有成员或者不可直接访问的成员,那么如果进一步派生的话,基类的全部成员就无法在新的派生类中直接访问<br/>
<font color="#FF0066">子类内部不报错<br/></font> 
<font color="#FF0066">通过对象访问报错<br/></font> 
(3)保护继承:<br/> 当类的继承方式是保护继承,即protected时,父类的公有成员和保护成员以保护成员的身份出现在子类中,在子类内部可以互相访问,但在类外通过对象就不能访问和操作,而父类private中的成员在子类中还是子类外都不能直接访问<br/>
<font color="#FF0066">子类内部不报错<br/></font> 
<font color="#FF0066">通过对象访问报错<br/></font> 
以上所有实验的代码
<font color="#FF0066">以Point类为父类,Recetangle为子类的源代码<br/></font>
头文件声明:<br/>
1#ifndef POINT_H 2#define POINT_H 3 4//Point类定义 5 6class Point 7{ 8public: 9 void initP(float xx , float yy ) ; 10 void move(float xoff, float yoff); 11 float getX() const; 12 float getY() const; 13private: 14 float x, y; 15}; 16 17//retangle类定义 18class Recetangle:private Point 19{ 20public: 21 void initR(float x, float y, float w, float h); 22 float getWidth() const; 23 float getHeight() const; 24private: 25 float w, h; 26}; 27
头文件函数实现:<br/>
1#include "point.h" 2#include<iostream> 3 4using namespace std; 5 6//point类函数实现 7 void Point::initP(float xx=0, float yy = 0) 8{ 9 x=xx; 10 y=yy; 11} 12void Point::move(float xoff, float yoff) 13{ 14 x += xoff; 15 y += yoff; 16} 17float Point::getX() const 18{ 19 return x; 20} 21float Point::getY() const 22{ 23 return y; 24} 25 26 27//Recetangle类函数实现 28 void Recetangle::initR(float x, float y, float w, float h) 29{ 30 initP(x, y);//私有继承,公有成员子类内部可以访问 31 this->w = w; 32 this->h = h; 33} 34float Recetangle::getHeight() const 35{ 36 return h; 37} 38float Recetangle::getWidth() const 39{ 40 return w; 41}
main函数:<br/>
1#include"point.h" 2#include <iostream> 3 4using namespace std; 5 6int main() 7{ 8 /*Recetangle test; 9 test.initR(2, 3, 20, 30); 10 test.move(3, 2); 11 cout << test.getX() << " " 12 << test.getY ()<< " " 13 << test.getWidth() << " " 14 <<test.getHeight() << " " 15 << endl;*/ 16 17 //Recetangle test2; 18 //test2.getX();//以私有继承,在类外通过对象进行访问,编译器报错 19 //test2.getY(); 20 21 //Recetangle test3; 22 //test3.getX(); 23 //test3.initP();//以保护继承,在类外不能通过对象访问 24 25 return 0; 26}
<font color="#FF0066">以Person类为父类,Student为子类的源代码<br/></font>
头文件声明:<br/>
1#ifndef PCH_H 2#define PCH_H 3 4#include<string> 5 6using namespace std; 7 8class Person 9{ 10public: 11 Person(); 12 ~Person(); 13 void Inputinfo(); 14 void Showinfo() const; 15private: 16 string name; 17protected: 18 int age; 19 20}; 21class Student:public Person 22{ 23public: 24 Student(); 25 void Inputinfo2(); 26 //void Inputinfo();//同名隐藏实验 27 void Showinfo2() const; 28 29private: 30 float grades; 31 int id; 32};
头文件中函数实现:<br/>
1#include "pch.h" 2#include<iostream> 3#include<string> 4 5using namespace std; 6 7 8/****Person类成员函数实现****/ 9 10//功能:构造函数 11Person::Person():name(name),age(age){} 12 13//功能:析构函数,人数减1 14Person::~Person(){} 15 16//功能:输入用户名字、年龄 17void Person::Inputinfo() 18{ 19 cout << "Pleasing input your name" << endl; 20 cin >> name; 21 cout << "Pleasing input your age" << endl; 22 cin >> age; 23} 24 25//功能:显示用户名字、年龄 26void Person::Showinfo() const 27{ 28 cout << "用户名: " << name << " \t " << "年龄 :" << age; 29 30} 31 32 33 34/****Student类成员函数的实现****/ 35 36//功能:Student类中构造函数实现 37Student::Student():id(id),grades(grades){} 38 39//功能:输入学生名字、年龄、学号、成绩 40void Student::Inputinfo2() 41{ 42 Inputinfo(); 43 cout << "Pleasing input your id" << endl; 44 cin >> id; 45 cout << "Pleasing input your grades" << endl; 46 cin >> grades; 47} 48 49////功能:输入学生学号、成绩(实现同名隐藏,通过对象操作时同名函数采取就近原则) 50//void Student::Inputinfo() 51//{ 52// cout << "Pleasing input your id" << endl; 53// cin >> id; 54// cout << "Pleasing input your grades" << endl; 55// cin >> grades; 56//} 57 58//功能:显示学生名字、年龄、学号、成绩 59void Student::Showinfo2() const 60{ 61 Showinfo(); 62 cout << "\t"; 63 cout << "学号: " << id << " \t " << "成绩: " << grades << endl; 64} 65 66////测试子类不能直接访问父类私有成员,编译器报错 67//void Student::Showinfo2() const 68//{ 69// cout << name 70// << age; 71//} 72 73 74////测试以public继承,父类的公有成员和保护成员在子类内部可以直接访问,编译器不报错 75//void Student::Showinfo2() const 76//{ 77// Showinfo();//父类公有成员 78// cout << age;//在做这步实验时,将原本私有成员的age改成了保护成员 79// cout << "\t"; 80// cout << "学号: " << id << " \t " << "成绩: " << grades << endl; 81//}
main函数:<br/>
1#include "pch.h" 2#include <iostream> 3#include<string> 4 5using namespace std; 6 7 8int main() 9{ 10 /*Person p1; 11 p1.Inputinfo(); 12 p1.Showinfo();*/ 13 14 Student stu1; 15 //stu1.Inputinfo();//同名隐藏前,原本Person类中Inputinfo函数输入的是name和age 16 stu1.Inputinfo2(); 17 stu1.Showinfo2(); 18 19 return 0; 20}