一、前言
继承机制,可以利用已有的数据类型来定义新的数据类型。所定义的新的数据类型不仅拥有新定义的成员,而且还同时拥有旧的成员。
二、继承定义
在c++语言中,我们称已存在用来派生新类的类称为基类,也称为父类。由基类派生出来的新类称为派生类,也称作子类。
一个派生类可以从一个类中派生,也可以从多个类中派生。从一个基类中派生的继承称为单继承,从多个基类中派生的继承称为多继承。
派生类继承基类后,派生类中就有有了基类中的部分方法和成员,主要继承了基类中除了构造函数和析构函数之外的所有方法和成员。
这里提出一个问题:派生类的内存布局,都继承了基类中的什么东西?
由上到下,先是基类的数据变量,再是派生类的数据变量,派生类继承基类由上到下依次继承。派生类中可以存在和基类相同的变量,因为作用域不同。
三、三种继承方式
继承的方式有public、private、protected。
基类中不同访问限定符下的成员以不同的继承方式继承
总结:
(1)当两个类产生了继承关系,而继承方式是public,那么基类下的public成员会被继承到派生类的public下面;基类下的protected成员会被继承到派生类的protected成员下;基类的privated成员将会无法访问。
(2)当两个类产生了继承方式,而继承方式是protected,那么基类下的public成员会被继承到派生类的protected下面;基类下的protected成员会被继承到派生类的protected成员下;基类的privated成员将会无法访问。
(3)当两个类产生了继承关系,而继承方式是private,那么基类下的public成员会被继承到派生类的private下面;基类下的protected成员会被继承到派生类的private成员下;基类的privated成员将会无法访问。
四、代码举例实现
1、公有继承(public)
class Student
{
public:
Student(string s,int g,int a)
{
cout<<"Constuct Student"<<endl;
name=s;
grade=g;
age=a;
}
void print()
{
cout<<"Student:"<<endl;
cout<<"name: "<<name<<endl;
cout<<"grade: "<<grade<<endl;
cout<<"age: "<<age<<endl;
}
protected:
string name;
int grade;
private:
int age;
};
class GoodStudent :public Student
{
public:
GoodStudent(string s,int g,int a):Student(s,g,a)
{
cout<<"Constuct GoodStudent"<<endl;
}
/*
公有继承方式,会把基类的公有成员(变量和函数)继承到子类公有成员,保护成员
变成基类的保护成员,但是私有成员子类也一样不可以访问
*/
void print1()
{
cout<<"GoodStudent:"<<endl;
cout<<"name: "<<name<<endl;
cout<<"grade: "<<grade<<endl;
//cout<<"age: "<<age<<endl; //error 基类中的私有成员不能被继承
cout<<endl;
}
};
int main()
{
GoodStudent s("Yanghuaixu",80,22);
s.print(); //派生类可以访问基类中的成员方法
s.print1();
return 0;
}
运行结果:
根据结果可以看出:
(1)基类中的共有成员,在子类中可以继承为自己的共有成员,子类可以进行访问,在外部可以访问
(2)基类中的保护成员,在子类中可以继承为自己的保护成员,子类可以进行访问,在外部不可以访问
(3)基类中的私有成员,子类不能进行访问,只有基类才可以进行访问
2、保护继承(protected)
class Student
{
public:
Student(string s,int g,int a)
{
cout<<"Constuct Student"<<endl;
name=s;
grade=g;
age=a;
}
void print()
{
cout<<"Student:"<<endl;
cout<<"name: "<<name<<endl;
cout<<"grade: "<<grade<<endl;
cout<<"age: "<<age<<endl;
}
string name;
int grade;
private:
int age;
};
class GoodStudent :protected Student
{
public:
GoodStudent(string s,int g,int a):Student(s,g,a)//调用基类中的构造函数,构造基类
{
cout<<"Constuct GoodStudent"<<endl;
}
/*
保护继承方式,会把基类的公有成员或者保护成员(变量和函数)变成子类的保护成员,但是私有成员子类也一样不可以访问
*/
void print1()
{
cout<<"GoodStudent:"<<endl;
cout<<"name: "<<name<<endl;
cout<<"grade: "<<grade<<endl;
//cout<<"age: "<<age<<endl; //error 基类中的私有成员不能被继承
cout<<endl;
}
};
int main()
{
GoodStudent s("Yanghuaixu",80,22);
//s.print(); //子类通过protected继承,公有成员方法变成了protected属性,不能进行直接访问
s.print1();
return 0;
}
运行结果:
可以看出:
(1)基类中的公有成员,子类中继承为自己的保护成员,基类可以进行访问,子类不可以直接进行访问
(2)基类中的保护成员,子类中继承为自己的保护成员,基类可以进行访问,子类不可以直接进行访问
(3)基类中的私有成员,子类不能够进行继承,子类不能够访问基类中的私有成员方法
3、私有继承(private)
class Student
{
public:
Student(string s,int g,int a)
{
cout<<"Constuct Student"<<endl;
name=s;
grade=g;
age=a;
}
void print()
{
cout<<"Student:"<<endl;
cout<<"name: "<<name<<endl;
cout<<"grade: "<<grade<<endl;
cout<<"age: "<<age<<endl;
}
string name;
int grade;
private:
int age;
};
class GoodStudent :private Student
{
public:
GoodStudent(string s,int g,int a):Student(s,g,a)//调用基类中的构造函数,构造基类
{
cout<<"Constuct GoodStudent"<<endl;
}
/*
私有继承方式,会把基类的公有成员或者保护成员(变量和函数)变成子类的私有成员,但是私有成员子类也一样不可以访问
*/
void print1()
{
cout<<"GoodStudent:"<<endl;
cout<<"name: "<<name<<endl;
cout<<"grade: "<<grade<<endl;
//cout<<"age: "<<age<<endl; //error 基类中的私有成员不能被继承
cout<<endl;
}
};
int main()
{
GoodStudent s("Yanghuaixu",80,22);
//s.print(); //子类通过private继承,公有成员方法变成了private属性,不能进行直接访问
s.print1();
return 0;
}
运行结果:
可以看出:
(1)基类公有成员,子类中继承为自己的私有成员,在派生类可以访问,在外部不可以访问。
(2). 基类保护成员,子类中继承为自己的私有成员,在派生类可以访问,在外部不可以访问。
(3) 基类私有成员,子类一样不可以访问基类的私有成员