1. 繼承與派生概述
1.1 繼承與派生是同一過程從不同的角度看
- 保持已有類的特性而構造新類的過程稱爲繼承
- 在已有類的基礎上新增自己的特性而產生新類的過程稱爲派生
被繼承的已有類稱爲基類(或者父類)
派生出的新類稱爲派生類(或子類)
直接參與派生出某類的基類稱爲直接基類
基類的基類甚至更高的基類稱爲間接基類
繼承的目的:實現設計與代碼的重用
派生的目的:當新的問題出現,原有程序無法解決(或者不能完全解決)時,需要對原有的程序進行改造。
2. 繼承時派生類的定義
- 單繼承時派生類的定義
class 派生類名:繼承方式 基類名 //單繼承只從一個基類進行繼承
{
成員聲明;
}
例:
class Derived:public Base
{
public:
Derived();
~Derived();
};
- 多繼承時派生類的定義
class 派生類名:繼承方式1 基類名1, 繼承方式2 基類名2,... //多繼承
{
成員聲明;
}
注意:每一個“繼承方式”,只用於限制對緊隨其後之基類的繼承。
例:
class Derived:public Base1, private Base2
{
Derived();
~Derived();
};
派生類的構成:
- 吸收基類成員,默認情況下派生類包含了全部基類中除構造函數和析構函數之外的所有成員
- 改造基類成員,如果派生類聲明瞭一個和某類成員同名的新成員,派生的新成員就隱藏或覆蓋了外層同名成員。
- 添加新的成員,派生類增加新成員使派生類在功能上有所發展。
3. 繼承方式簡介
3.1 不同的繼承方式的影響主要體現在:
- 派生類成員對基類成員的訪問權限
- 通過派生類對象對基類成員的訪問權限
3.2 三種繼承方式:
- 公有繼承
- 私有繼承
- 保護繼承
3.3 公有繼承(public)
繼承的訪問控制:
- 基類的public和protected成員:訪問屬性在派生類中保持不變;
- 基類的private成員:不可直接訪問。
訪問權限:
- 派生類中的成員函數:可以直接訪問基類中的public和protected成員,但不能直接訪問基類的private成員;
- 通過派生的對象:只能訪問public成員。
公有繼承的例子:
//Point.h
#ifndef _POINT_H
#define _POINT_H
class Point{
public:
void initPoint(float x = 0, float y = 0){ this->x = x; this->y = y; }
void move(float offX, float offY){ x += offX; y += offY; }
float getX() const { return x; }
float getY() const { return y; }
private:
float x, y;
};
#endif
//Rectangle.h
#include "Point.h"
class Rectangle :public Point{ //派生類定義部分
public: //新增公有成員函數
void initRectangle(float x, float y, float w, float h){
initPoint(x, y); //調用基類公有成員函數
this->w = w;
this->h = h;
}
float getH() const { return h; }
float getW() const { return w; }
private: //新增私有數據成員
float w, h;
};
#include <iostream>
#include "Rectangle.h"
using namespace std;
int main()
{
Rectangle rect;
rect.initRectangle(2, 3, 20, 10);
rect.move(3, 2);
cout << "The data of rect(x,y,w,h):" << endl;
cout << rect.getX() << ", "
<< rect.getY() << ", "
<< rect.getW() << ", "
<< rect.getH() << endl;
system("pause");
return 0;
}
3.4 私有繼承
繼承的訪問控制:
- 基類的public和protected成員:都以private身份出現在派生類中;
- 基類的private成員:不可以直接訪問。
訪問權限:
- 派生類中的成員函數:可以直接訪問基類中的public和protected成員,但不能直接訪問基類的private成員;
- 通過派生類的對象:不能直接訪問從基類繼承的任何成員。
私有繼承例子:
//Point.h
#ifndef _POINT_H
#define _POINT_H
class Point{
public:
void initPoint(float x = 0, float y = 0){ this->x = x; this->y = y; }
void move(float offX, float offY){ x += offX; y += offY; }
float getX() const { return x; }
float getY() const { return y; }
private:
float x, y;
};
#endif
//Rectangle.h
#ifndef _RECTANGLE_H
#define _RECTANGLE_H
#include "Point.h"
class Rectangle :private Point{ //派生類定義部分
public: //新增公有成員函數
void initRectangle(float x, float y, float w, float h){
initPoint(x, y); //調用基類公有成員函數
this->w = w;
this->h = h;
}
void move(float offX, float offY){ Point::move(offX, offY); }
float getX() const { return Point::getX(); }
float getY() const { return Point::getY(); }
float getH() const { return h; }
float getW() const { return w; }
private: //新增私有數據成員
float w, h;
};
#endif
#include <iostream>
#include "Rectangle.h"
using namespace std;
int main()
{
Rectangle rect;
rect.initRectangle(2, 3, 20, 10);
rect.move(3, 2);
cout << "The data of rect(x,y,w,h):" << endl;
cout << rect.getX() << ", "
<< rect.getY() << ", "
<< rect.getW() << ", "
<< rect.getH() << endl;
system("pause");
return 0;
}
3.5 protected成員的特點與作用
- 對建立其所在類的模塊來說,它與private成員的性質相同
- 對於其派生類來說,它與public成員的性質相同
- 即實現了數據隱藏,又方便繼承,實現代碼重用。