公開(public)繼承


假設您先前已經撰寫了一些2D繪圖相關類別,現在打算將之擴充為適用於3D繪圖,3D的觀念是2D的延伸,許多2D繪圖時所使用的功能都可以留下來加以擴 充,在C++中您不用重寫所有的類別,您可以「繼承」(Inherit)原先已定義好的類別,然後加以擴充。

例如繪圖中最基本的點類別,您原先已定義好一個Point2D類別,您繼承它並將之擴充為Point3D類別,在繼承的關係中,稱被繼承的類別為「父類 別」(Parent class)或「基礎類別」(Base class),而繼承父類別的就稱之為「子類別」(Child class)或「衍生類別」(Derived class),在繼承時您使用 : 運算子,並指定其繼承方式,在繼承的權限關係上,公開繼承是最常見的,先由這個開始說明繼承的概念。

直接使用一個實際例子來說明好了,先定義Point2D:
  • Point2D.h
class Point2D { 
public:
Point2D() {
_x = 0;
_y = 0;
}
Point2D(int x, int y) : _x(x), _y(y) {
}
int x() {return _x;}
int y() {return _y;}
void x(int x) {
_x = x;
}
void y(int y) {
_y = y;
}
private:
int _x;
int _y;
};

接著定義Point3D類別,它公開繼承Point2D類別:
  • Point3D.h
#include "Point2D.h"

class Point3D : public Point2D {
public:
Point3D() {
_z = 0;
}
Point3D(int x, int y, int z) : Point2D(x, y), _z(z) {
}
int z() {return _z;}
void z(int z) {_z = z;}

private:
int _z;
};

當您公開繼承某個類別時,該成員的所有public成員都可以在衍生類別中被呼叫使用,而private成員則不可以直接在衍生類別中被呼叫使用;在這個 例子中,Point2D中已經有_x, _y兩個成員,而繼承之後新增_z成員,在函式上您新增public的z()方法,而x()與y()直接繼承父類別中已定義的內容。

在繼承某個類別之後,您可以一併初始父類別的建構函式,以完成相對應的初始動作,這可以使用 : 運算子並加上父類別建構函式名稱,至 於無參數的預設建構函式,在生成衍 生類別物件時,基底類別的無參數建構函式會自動被呼叫。

父類別的public成員可以直接在衍生類別中使用,而private成員則不行,private類別只限於定義它的類別來存取,如果您想要與父類別的 private成員溝通,就只能透過父類別中繼承下來的public函式成員,例如上例中的x()與y()方法。

來看看一個使用Point3D的例子:
  • main.cpp
#include <iostream>
#include "Point3D.h"

using namespace std;

int main() {
Point3D p1(1, 3, 4);
Point3D p2;

cout << "p1: ("
<< p1.x() << ", "
<< p1.y() << ", "
<< p1.z() << ")"
<< endl;

p2.x(5);
p2.y(7);
p2.z(8);

cout << "p2: ("
<< p2.x() << ", "
<< p2.y() << ", "
<< p2.z() << ")"
<< endl;

return 0;
}

執行結果:

p1: (1, 3, 4)
p2: (5, 7, 8)

公開繼承時,父類別與子類別之間是"is-a"的 關係,白話來說,假 設父類別是A類的話,公開繼承的子類也「是一種」A 類。