在面向?qū)ο缶幊讨凶钪匾母拍钪痪褪抢^承。繼承允許我們根據(jù)一個類來定義另一個類,這使得創(chuàng)建和維護一個應(yīng)用程序更加的容易。這也提供了一個重用代碼功能和快速實現(xiàn)的機會。
當(dāng)創(chuàng)建一個類,不是寫全新的數(shù)據(jù)成員和成員函數(shù)的時候,程序員可以指定新類,這個類可以繼承現(xiàn)有類的成員。這個現(xiàn)有的類稱為基類,這個新類稱為派生類。
繼承的概念其實是一種關(guān)系。例如,哺乳動物是動物,狗是哺乳動物,因此狗是動物等等。
一個類可以繼承多個類,這就意味著它可以從多個基類中繼承數(shù)據(jù)和函數(shù)。為了定義一個派生類,我們可以使用一個類繼承列表來指定基類。一個類繼承列表指定一個或多個基類,類繼承列表形式如下:
class derived-class: access-specifier base-class
在這里 access-specifier 是 public 、 protected 或者 private ,base-class 是之前定義的類的名稱。如果不使用 access-specifier ,那么在默認(rèn)情況下它是私有的。
考慮一個基類的 shape 和其派生類 Rectangle 的繼承情況如下:
#include <iostream>
using namespace std;
// Base class
class Shape
{
public:
void setWidth(int w)
{
width = w;
}
void setHeight(int h)
{
height = h;
}
protected:
int width;
int height;
};
// Derived class
class Rectangle: public Shape
{
public:
int getArea()
{
return (width * height);
}
};
int main(void)
{
Rectangle Rect;
Rect.setWidth(5);
Rect.setHeight(7);
// Print the area of the object.
cout << "Total area: " << Rect.getArea() << endl;
return 0;
}
上面的代碼編譯和執(zhí)行時,它產(chǎn)生以下結(jié)果:
Total area: 35
一個派生類可以訪問所有它的基類的非公有類型的成員。因此不希望被派生類的成員函數(shù)訪問的基類成員應(yīng)該在基類中聲明為私有類型。
我們可以根據(jù)誰能訪問它們總結(jié)出不同的訪問類型,如下表格中所示:
訪問權(quán)限 | public | protected | private |
---|---|---|---|
同一個類 | 是 | 是 | 是 |
派生類 | 是 | 是 | 否 |
類外成員 | 是 | 否 | 否 |
派生類繼承了基類的所有方法,以下情況除外:
當(dāng)從一個基類派生一個子類的時候,公共基類可以通過 public ,protected ,或者 private 方式被繼承。繼承方式被 access-specifier 指定,正如上面解釋的。
我們幾乎不使用protected或私有private 繼承,但public繼承是常用的。在使用不同類型的繼承的時候,應(yīng)用規(guī)則如下:
一個C++類可以繼承多個類的成員,多繼承語法如下:
class derived-class: access baseA, access baseB....
在這里 access 是 public ,protected ,或者是 private ,并且每一個基類將有一個 access 類型,他們將由逗號分隔開,如上所示。讓我們試試下面的例子:
#include <iostream>
using namespace std;
// Base class Shape
class Shape
{
public:
void setWidth(int w)
{
width = w;
}
void setHeight(int h)
{
height = h;
}
protected:
int width;
int height;
};
// Base class PaintCost
class PaintCost
{
public:
int getCost(int area)
{
return area * 70;
}
};
// Derived class
class Rectangle: public Shape, public PaintCost
{
public:
int getArea()
{
return (width * height);
}
};
int main(void)
{
Rectangle Rect;
int area;
Rect.setWidth(5);
Rect.setHeight(7);
area = Rect.getArea();
// Print the area of the object.
cout << "Total area: " << Rect.getArea() << endl;
// Print the total cost of painting
cout << "Total paint cost: $" << Rect.getCost(area) << endl;
return 0;
}
上面的代碼編譯和執(zhí)行時,它產(chǎn)生以下結(jié)果:
Total area: 35
Total paint cost: $2450