C 的繼承與派生(一)

2021-06-28 20:10:39 字數 4231 閱讀 2965

1.相關概念

物件導向程式設計有4個主要特點:抽象、封裝、繼承和多型性。其中,繼承性為其最重要的特徵。

在c++中,「繼承」就是在乙個存在的類的基礎上建立乙個新的類。已存在的類稱為「基類」或「父類」。新建立的類稱為「派生類」或「子類」。

派生與繼承是一對相對的詞,乙個新類從已有類那裡獲得其已有的特性,叫作繼承,那麼,從另乙個角度來說,從已有類產生乙個新的子類,就叫做派生。

乙個派生類只由乙個基類派生,稱為單繼承;乙個派生類由兩個或多個基類派生,稱為多重繼承。從以上所說,我們可以大致的看出派生類與基類的關係:派生類是積累的具體化,而基類則是派生類的抽象。

2.派生類的宣告

宣告派生類的一般方式為:

class 派生類名:[繼承方式]  基類名

;

繼承方式包括:public(公用的),private(私有的),protected(受保護的),繼承方式可不寫,不寫則預設為private(私有的)。

不同的繼承方式會使派生類中的、從基類中繼承過來的成員的、訪問屬性不同。具體在第4小節展開說明。

3.派生類的構成

派生類的成員包括從基類繼承過來的成員和自己增加的成員兩個部分,但是並不是說把基類的成員和派生類新增的成員簡單相加就是派生類了。構造乙個派生類包括以下3個部分:

(1)從基類接收成員

這裡要注意的是派生類必須全部接受基類的成員,即不可以選擇性的接受基類的成員。

(2)調整從基類接收的成員

這裡有兩個方面,第一方面是可通過指定的繼承方式,改變基類成員在派生類中的訪問屬性;另一方面,是在派生類中宣告乙個與基類同名的成員,則派生類中新成員會覆蓋掉基類中的同名成員。(注:若是成員函式,不僅要使函式名相同,引數的個數與型別也要相同,否則,則為函式過載而非覆蓋。)

(3)在宣告派生類時增加的成員

在宣告派生類時 ,一般還應當自己定義派生類的建構函式和析構函式,因為建構函式和析構函式是不能從基類繼承的。

4.派生類成員的屬性

因派生類中即有基類成員又有派生類新增成員,所以就產生了這兩部分成員的關係和訪問屬性的問題。

派生類新增成員的屬性一般在定義時就確定了,而基類成員在派生類的訪問屬性,不僅要考慮在基類中該成員所宣告的訪問屬性,還要考慮派生類所宣告的對積累的繼承方式。在第2節的時候提到,在派生類中,對積累的繼承方式包括:public(公用的),private(私有的),protected(受保護的)三種,下面我們詳細介紹這三種繼承方式。

在介紹三種繼承方式之前,先讓我來建立乙個基類student如下:

#ifndef student

#define student

#include

#include

using namespace std;

class student

void display()

void display_1()

由以上**,我們可以看到,公有派生類可以通過呼叫公有派生類的公有成員函式,來間接地呼叫公有基類的私有成員。

4.2私有繼承

在定義乙個派生類時,繼承方式指定為private的,稱為私有繼承,用私有繼承方式建立的派生類稱為私有派生類(private derived class),其基類稱為私有基類(private class)。

私有派生類的成員在派生類中的訪問屬性見下表1.2

表1.2  私用基類的成員在派生類中的訪問屬性

在基類的訪問屬性

繼承方式

在派生類中的訪問屬性

private(私有)

private(私有)

不可訪問

public(公用)

private(私有)

private(私有)

protected(保護)

private(私有)

private(私有)

下面我們定義乙個私有派生類student2:

#ifndef student2

#define student2

#include"class.h"

#include

#include

using namespace std;

class student2:private student

void display_2()

從中我們得出了結論:(1)不能通過私有派生類物件呼叫從私有基類繼承過來的任何成員(如以上主函式的錯誤一)。

(2)私有派生類的成員函式還是可以呼叫私有基類的公有成員的。

從結論(1)、(2)中,我們可以推知:雖然在派生類外,我們不能通過派生類物件呼叫私有基類的公有成員函式(結論(1)),但是可以通過私有派生類的成員函式呼叫私有基類的公用成員函式(結論(2))。

具體例子:

#ifndef student2

#define student2

#include"class.h"

#include

#include

using namespace std;

class student2:private student

void display_2(){

display();

cout<<"age:"<

<

在以上**中,在私有派生類的公用函式中呼叫了私有基類的公用成員函式,從而間接地呼叫了私有基類的私有成員。

4.3保護繼承

在定義乙個派生類時,繼承方式指定為protect的,稱為保護繼承,用保護繼承方式建立的派生類稱為保護派生類(protected derived class),其基類稱為保護基類(protected class)。

由protect宣告的成員稱為「受保護的成員」,或簡稱「保護成員」。保護成員不能被類外訪問,可以被派生類的成員函式直接呼叫。

保護派生類的成員在派生類中的訪問屬性見下表1.3

表1.3  保護基類的成員在派生類中的訪問屬性

在基類的訪問屬性

繼承方式

在派生類中的訪問屬性

private(私有)

protected(保護)

不可訪問

public(公用)

protected(保護)

protected(保護)

protected(保護)

protected(保護)

protected(保護)

下面比較一下私有繼承和保護繼承

在一次的繼承中,私有繼承和保護繼承實際上起的作用都是一樣的,即在類外不能訪問任何成員,而派生類中可以通過成員函式訪問基類中的公用成員和保護成員。但如果繼續派生,在新的派生類中,兩種繼承的派生類就不一樣了。再派生一次,原先的私有派生類的所有成員都變不可訪問,而原先的保護派生類的公用成員和保護成員變為保護成員,還可以被派生類的成員函式呼叫。

4.4在派生類中,成員的訪問屬性

如下表1.4

派生類中的訪問屬性

在派生類中

在派生類外部

在下一層公用派生類中

公用可以

可以可以

保護可以

不可以可以

私有可以

不可以不可以

不可訪問

不可以不可以

不可以

注:在討論乙個成員的訪問屬性時,要注意前提,就是在哪乙個作用域中。同乙個成員在不同的作用域中是可以表現出不同的訪問屬性的。

5.多級派生(相關概念)

類a為基類,類b是類a的派生類,類c是類b的派生類,則類c也是類a的派生類。類b稱為類a的直接派生類,類c稱為類a的間接派生類。類a是類b的直接基類,是類c的間接基類。

在多級派生中,如果採用私有繼承方式,派生若干次後,基類的所有成員都會變得不可訪問;而如果採用保護繼承派生若干次,由於派生類外是無法訪問派生類中的任何成員的,所以很難記清楚哪些成員可以訪問,哪些成員不可以訪問,容易出錯。所以,在實際應用中,常用的是公用繼承。

C 繼承與派生(一)

保持已有類的特性而構造新類的過程。實現 的重用和設計的重用。比如繼承乙個抽象類是為了繼承它的設計,抽象類並沒有完全實現,但是把介面設計好了,剩下的要自己實現 當新問題出現,原有程式不能解決問題時,需要對原有程式進行改造。吸收基類成員 改造基類成員 可以重寫同名的函式,覆蓋基類中的函式,資料成員也會隱...

C 繼承與派生(一)

1.1 繼承與派生是同一過程從不同的角度看 被繼承的已有類稱為基類 或者父類 派生出的新類稱為派生類 或子類 直接參與派生出某類的基類稱為直接基類 基類的基類甚至更高的基類稱為間接基類 繼承的目的 實現設計與 的重用 派生的目的 當新的問題出現,原有程式無法解決 或者不能完全解決 時,需要對原有的程...

C 繼承與派生

派生新類 吸收已有類的成員 調整已有類成員和新增新的成員 class 派生類名 繼承方式 基類名1,繼承方式 基類名2,派生類成員宣告 繼承方式有 public protected private 預設 公有繼承 基類的公有和保護乘員的訪問屬性在派生類中不變,基類的私有成員不能直接訪問 型別相容規則...