C 三大特性之封裝,繼承,多型

2021-09-11 01:25:52 字數 4089 閱讀 7540

在嵌入式的軟體開發過程中大多是使用c這種面向過程的語言來開發,從效率上來說c語言已經非常高了,使用在硬體資源比較緊張的嵌入式系統來說是最好不過的選擇了,隨著硬體效能的提公升,以及硬體**的下降,c++逐漸應用於嵌入式系統中了,c++語言在編譯器開優化的情況下,**效率已經接近c語言了,並且提供了更高階的語言特性。(c語言也可以實現c++的特性linux核心就是使用了很多物件導向的思想)

c語言也可以實現封裝,使用struct關鍵字,把函式放進結構體中是從c到c++的根本改變(c語言使用函式指標)。將資料連同函式**在一起的能力可以用於建立新的資料型別,這稱之為封裝(encapsulation),封裝既是針對資料(屬性)也是針對函式(行為)。

封裝就是對現實世界的一種抽象。

事實上物件導向程式設計可以總結為一句話,「向物件傳送訊息」,實際上要做的所有事情就是建立一束物件並且給它們傳送訊息。

封裝為什麼好處呢?

隱藏實現:

在c語言中,struct與其它的資料結構一樣,沒有任何的規則,程式設計師可以struct中做他想做的任何事情,沒有途徑來強制任何的特殊行為。

c++語言中引入了三個新的關鍵字,用於在結構中設定訪問的邊界,public,private,protected。

在c++中使用class 關鍵字,它和c語言中的struct每乙個方面都是一樣的,除了class的成員預設是private的,而struct的成預設是public的。

如果乙個函式被宣告為friend時,就意味著它不這個類的成員函式,卻可以修改該類的私有成員,且必須被列在該類的定義當中,這是乙個特權函式,它突破了原有的訪問控制許可權。

c++中通過建立新的類來重用**,而不是從頭建立它們。繼承是對抽象的一種昇華。在程式設計實踐中將公共特性部分抽出來放在父類裡,了類則擁有特性化的有別於其它子類的特性。(is-a關係)

子類的訪問許可權:

繼承方式

基類的public成員

基類的protected成員

基類的private成員

public

仍為public

仍為protected

not access

protected

變為protected

仍為protected

not access

private

變為private

變為private

not access

組合( composition)

組合是另外一種**重用的方式。無論是組合還是繼承都能把子物件放在新型別中。組合通常是在希望新類內部具有已存在類的功能時使用,而不是希望已經存在類作為它的介面,嵌入乙個物件用以實現新類的功能,而新類的使用者看到的是新定義的介面而不是來自老類的介面,為此在新類的內部嵌入已存在類的private物件。(has-a關係)

繼承與靜態成員

多型是通過虛函式實現的。

多型是執行時動態繫結。

動態繫結的條件:

基類型別的引用或指標可以引用基類型別物件,也可以引用派生型別物件。

引用或指標的靜態型別與動態型別可以不同,這是c++支援多型的基礎。通過基類引用或指標呼叫基類中定義的函式時,並不能知道要執行的函式物件的確切型別,執行函式的物件有可能是基類型別也可能是派生型別的。

class base

};class devideda :public base

};class devidedb :public base};/

base *b = new devidedb ();

b->func(); //呼叫 devidedb::func();

函式定義為純虛函式說明,此函式為後代型別提供了可以覆蓋的介面,但是這個類中是不會呼叫,此外使用者不能建立此類的物件。此類為抽象基類。

class q_widgets_export qabstractbutton : public qwidget

;void qradiobutton::paintevent(qpaintevent *)

qabstractbutton 的所有派生類 qcheckbox, qpushbutton, qradiobutton, qtoolbutton都要實現irtual void paintevent(qpaintevent *e)介面。

摘自qt原始碼的 focusoutevent

void qabstractbutton::focusoutevent(qfocusevent *e)

在qabstractbutton的focusoutevent方法裡做特殊化的處理,再呼叫父類的focusoutevent做通用化的處理。

靜態的多型

出現在相同的作用域中(同乙個類中,同乙個檔案中)的兩個函式如果具有相同的名字且形參表不同見為函式的過載(overload function)。編譯器將根據所傳遞的實參型別來判斷呼叫的是哪乙個函式。函式不能僅僅基於不同的返回型別而實現過載。

錯誤的例子:

record lookup(const account&);

bool lookup(const account&);

record lookup(const account&acct);

record lookup(const account&);

typedef phone telno;

record lookup(const phone&);

record lookup(const telno&);

record lookup(phone);

record lookup(const phone);

正確的例子:

record lookup(phone&);

record lookup(const phone&);

record lookup(name);

record lookup(address);

通過操作符的過載,程式能夠針對類 型別的運算元定義不同的操作符版本。過載操作符是具有特殊名稱的函式,保留字operator後接需要定義的操作符符號,像其它函式一樣,過載操作符具有返回型別和形參列表。

格式:

object operator + (const objcet&,const object&);
內建型別的操作符,不能過載(不能過載int型別的「+」操作符)

過載一元操作符如果作為成員函式就沒有形參(顯式),如果作為非成員函式就有乙個形參,同樣的,過載二元操作符定義的成員時有乙個形參,定義為非成員函式時有兩個形參。

操作符定義為非成員函式時通常必須將它們設定為所操作類的友元(friend)

當子類與基類的成員同名時將遮蔽對基類成員的直接訪問。

class base

protected:

int mem;

};class derived :public base

//初始化derived::mem;

int getmem()

int getbasemem()

protected:

int mem;

}

在基類和子類中使用同一名字的成員函式,其行為與資料成一樣:在子類作用域中子類成員將遮蔽基類成員。即使函式原型不同,基類成員也會被遮蔽。

class base

;class derived :public base

base b;

derived d;

b.func();

d.func(2);

d.base::func();

d.func(); //error

《c++程式設計思想》

《c++ primer》

(圖)

C 三大特性之 封裝 繼承 多型

一 封裝 封裝是實現物件導向程式設計的第一步,封裝就是將資料或函式等集合在乙個個的單元中 我們稱之為類 被封裝的物件通常被稱為抽象資料型別。封裝的意義 封裝的意義在於保護或者防止 資料 被我們無意中破壞。在物件導向程式設計中資料被看作是乙個中心的元素並且和使用它的函式結合的很密切,從而保護它不被其它...

C 三大特性 封裝,繼承,多型

c 三大特性 封裝,繼承,多型 封裝 定義 封裝就是將抽象得到的資料和行為相結合,形成乙個有機的整體,也就是將資料與運算元據的源 進行有機的結合,形成類,其中資料和函式都是類的成員,目的在於將物件的使用者和設計者分開,以提高軟體的可維護性和可修改性 特性 1.結合性,即是將屬性和方法結合 2.資訊隱...

三大特性 封裝,繼承,多型

重寫方法的規則 1 引數列表必須完全與被重寫的方法相同,否則不能稱其為重寫而是過載。2 返回的型別必須一直與被重寫的方法的返回型別相同,否則不能稱其為重寫而是過載。3 訪問修飾符的限制一定要大於被重寫方法的訪問修飾符 public protected default private 4 重寫方法一定...