继承与多态(一)
目錄
?
一、繼承的概念:
二、公有繼承
三、私有繼承
四、保護繼承
五、保護繼承與保護成員的訪問
一、繼承的概念:
在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 | 不可訪問 |
???????????????????????????????????????????????????????????????????? 各種繼承方式下的訪問控制屬性
?
?
?
總結
- 上一篇: 项目的ar指什么_AR眼镜显示测评标准解
- 下一篇: antd table排序会触发到分页怎么