目录
一、继承的概念:
二、公有继承
三、私有继承
四、保护继承
五、保护继承与保护成员的访问
一、继承的概念:
在C++中可以用已有的类来定义新的类,新类将继承原有类的全部特性,原有类称为基类(父类),新继承的类被称为派生类(子类)。派生类拥有基类的特性称作继承,由基类产生派生类的过程称为派生。
继承与派生
一个基类可以有多个派生类,派生类作为基类,又可以有多个派生类,称为类层次,画成一个图的话,称为继承树。
单继承(单向继承):一个派生类有且只有一个基类,派生类可以看做是基类的特例。
多继承(多重继承):一个派生类有两个或两个以上的基类。
多层派生:派生类又作为基类,继续派生新的类。从继承的角度来看称为多重继承。
类层次图
二、公有继承
特点:
(1)基类的公有成员仍然为公有成员,可以由派生类对象和派生类成员函数直接访问。
(2)基类的私有成员在派生类中,无论是派生类成员还是派生类对象都无法直接访问。
(3)保护成员在派生类中依然是保护成员,可以通过派生类的成员函数访问,但不能由派生类的对象直接访问。
//Point.h
#include<iostream>
using namespace std;
class Point
{
public:Point(int x = 0,int y = 0){this->X = x;this->Y = y;}void move(int Offx,int Offy){X += Offx;Y += Offy;}void ShowPoint(){cout << "(" << X << "," << Y << ")" << endl;}private:int X;int Y;
};
从Point类派生出的Circle类
Circle类具备Point类的全部特征,同时也有自己的特点,Circle类有半径,Circle在继承Point类的同时添加新的成员。
//Circle.h
#include<iostream>
#include"Point.h"
using namespace std;const double PI = 3.14159;class Circle : public Point
{
public:Circle(int x,int y,double r):Point (x,y){this -> R = r;}double Area(){return PI * R * R;}void ShowCircle(){cout << "Centre of circle:" ;ShowPoint();//调用基类的Show函数cout << "R:" << R << endl;}
private:double R;//半径
};
//main.cpp
#include<iostream>
#include"Circle.h"
using namespace std;int main()
{Circle Cir(100,200,10);Cir.ShowCircle();cout << "area is " << Cir.Area() << endl;Cir.move(10,20);Cir.ShowPoint();return 0;
}
类名 | 成员名 | 访问权限 | ||
Circle:: | Point:: | X,Y | private | 不可访问 |
move() | public | public | ||
ShowPoint() | public | public | ||
R | private | |||
area() | public | |||
ShowCircle() | public | |||
Circle() | public |
类Circle的成员函数图 (public)
三、私有继承
特点:
(1)基类的公有成员和保护成员被继承后作为派生类的私有成员,派生类的其他成员函数可以直接访问它们,但是在类外,不能通过派生类的对象访问它们。
(2)基类的私有成员不可访问。
(3)经过私有继承之后,所有基类的成员都成为派生类的私有成员或不可访问的成员,如果进一步派生的,基类的成员函数将无法在新的派生类中被访问。相当于终止了基类的继续派生。
//Circle.h
#include<iostream>
#include"Point.h"
using namespace std;const double PI = 3.14159;
class Circle : private Point
{
public:Circle(int x,int y,double r):Point (x,y){this -> R = r;}double Area(){return PI * R * R;}void ShowCircle(){cout << "Centre of circle:" ;ShowPoint();//调用基类的Show函数cout << "R:" << R << endl;}void move(int Offx,int Offy){Point :: move(Offx,Offy);}private:double R;//半径
};
//main.cpp
#include<iostream>
#include"Circle.h"
using namespace std;int main()
{Circle Cir(100,200,10);Cir.ShowCircle();cout << "area is " << Cir.Area() << endl;Cir.move(10,20);
// Cir.ShowPoint();return 0;
}
我们通过基类名,在派生类重新定义了move()函数,将基类的move()函数封装在派生类的同名成员函数中。
类名 | 成员名 | 访问权限 | ||
Circle:: | Point:: | X,Y | private | 不可访问 |
move() | public | private | ||
ShowPoint() | public | private | ||
R | private | |||
area() | public | |||
ShowCircle() | public | |||
Circle() | public |
类Circle的成员函数图(private)
四、保护继承
//Circle.h
#include<iostream>
#include"Point.h"
using namespace std;const double PI = 3.14159;class Circle : protected Point
{//类成员定义
};
运行结果与私有继承相同。
类名 | 成员名 | 访问权限 | ||
Circle:: | Point:: | X,Y | private | 不可访问 |
move() | public | protected | ||
ShowPoint() | public | protected | ||
R | private | |||
area() | public | |||
ShowCircle() | public | |||
Circle() | public |
类Circle的成员函数图(protected)
private\protected两种继承方式下,基类所有成员在派生类中的访问属性都是一样的。
当派生类作为新的基类继续派生时,private和protected两种继承方式的区别:
假设类B以私有方式继承了类A,则类B无论以什么方式派生出类C,类C的成员和对象都不能访问间接从类A中继承来的成员。如果类B是以保护方式继承类A,那么类A中的公有和保护成员在类B中都是保护成员。
类B在派生出类C后,如果是公有派生或者保护派生,则类A中的公有和保护成员被类C间接继承后,类C的成员函数可以访问间接从类A中继承来的成员。
五、保护继承与保护成员的访问
//Point.h
#include<iostream>
using namespace std;class Point
{
public:Point(int x = 0,int y = 0){this ->X = x;this -> Y = y;}void move(int Offx,int Offy){X += Offx;Y += Offy;}void ShowPoint(){cout << "(" << X << "," << Y << ")" << endl;}
protected :int X;int Y;
};
//Circle.h
#include<iostream>
#include"Point.h"
using namespace std;const double PI = 3.14159;class Circle:protected Point
{
public:Circle(int x,int y,double r) : Point(x,y) {this -> R = r;}double area(){return PI * R * R;}void ShowCircle(){cout << "Centre of circle:";ShowPoint();cout << "R: " << R << endl;}
protected: double R;};
//Cylinder.h
#include<iostream>
#include"Circle.h"
using namespace std;class Cylinder:protected Circle
{
public:Cylinder(int x,int y,double r,int h):Circle(x,y,r){this -> H = h;}double area(){return 2 * Circle :: area() + 2 * PI * R * H;}double volume(){return Circle :: area() * H;}void ShowCylinder(){ShowCircle();cout << "height of Cylinder"<< H <<endl;}
private:double H;
};
//main.cpp
#include<iostream>
#include"Cylinder.h"
using namespace std;
int main()
{Cylinder Cy(100,200,10,5);Cy.ShowCylinder();cout << "total area :" << Cy.area() << endl;cout << "volume is " << Cy.volume() << endl;return 0;
}
对于自子类来说,保护成员与公有成员具有相同的访问特性。
基类属性 继承方式 | public
| protected
| private
|
public | public | protected | 不可访问 |
protected | protected | protected | 不可访问 |
private | private | private | 不可访问 |
各种继承方式下的访问控制属性