類的三方法:封裝,繼承,多態。
封裝:使用一整套方法去創建一個新的類型,這叫類的封裝。
繼承:從一個現有的類型基礎上,稍作改動,得到一個新的類型的方法,叫類的繼承。
多態:當有幾個不同的子類對象時,對象調用的函數會依據對象類型來調用相應類型的成員函數。
繼承
1. 繼承的主要目的是為了代碼復用。
創建子類對象時,先創建父類,再創建子類。
析構時,先析構子類,再析構父類。
2. 訪問權限:public, protected, private.
protected表示這種成員可以被子類繼承和訪問,但是外界卻像private一樣不可訪問。
父類的private成員并不是不繼承,而是對子類擴展的成員函數不可見。
public派生規則:
父類成員訪問權限 子類繼承自父類成員的訪問限定
public public
protected protected
private 不可見
protected派生規則:
父類成員訪問權限 子類繼承自父類成員的訪問限定
public protected
protected protected
private 不可見
private派生規則:
父類成員訪問權限 子類繼承自父類成員的訪問限定
public private
protected private
private 不可見
3.?類型轉換
父類A子類B
A *p = new B; 可以
B *p = new A; 不可以
p調用的成員方法為父類(A)的方法,非子類B的成員方法。屬編譯時綁定(因p的指針類型為A *),如要訪問子類,需要使用多態(父類相應方法定義為virtual)。
A a;
B *p;
p = &a; 可以
p訪問成員變量時可能越界(因p的成員變量多余a)
多態
聲明為vitual的成員函數稱為虛函數。
有虛函數的類都有一個隱含的指針成員vptr,指向一個虛函數表。(一個類一個)
每個父類或子類都各自有一張虛函數表。在構造對象時,對象的vptr成員指向該類的虛函數表。
包含虛函數的類的sizeof應多加4個字節,用于存放vptr(虛函數表指針)。
一旦某個函數在父類中聲明為virtual,在所有繼承它的子類中這個函數也是virtual的,子類可以不必寫virtual關鍵字。
聲明為virtual的函數,在運行時確定執行體,屬動態綁定,dynamic binding。調用子類的具體實現。如果一個成員函數聲明為virtual并在末尾加上=0而沒有提供函數的實現,稱為虛函數,擁有虛函數的類稱為抽象類,抽象類不能實例化(或者說不能創建該類的對象),而只能被其他類繼承。
抽象類也稱為接口,繼承了某個抽象類也稱實現了某個接口。
?