總結 繼承和多型

2021-10-09 08:58:05 字數 3169 閱讀 1234

之所以把繼承和多型放在一起,是因為二者在關係上很難分開。

在已有類的基礎上建立新類。新類包含了原始類的資料成員和方法。

建立新類的主要原因就是新增替換功能。

繼承的執行方式是單向的,父類與子類有著明確的關係,子類知道與父類的關係,但是父類不知道與子類的關係。

其實這樣記不好記,從記憶體的角度去記比較好記。

從記憶體的大小上看很好區分。

father* p_father = new son;   // ok;

son *p_son = new father; // error

所以基類指標可以指向父類

father *p_father;p_father的定址能力father類的大小。

son* p_son;p_son的定址能力son類的大小。

#include using namespace std;

class father

};class son : public father

};int main(void)

我可以訪問積累中的protected,和public資料。

c++有乙個關鍵字可以禁止乙個類被繼承。關鍵字是final,只需要在類的名字後面加上final關鍵字。

class a final

學好繼承區別這兩個概念很重要:過載和重寫區別:過載,在同一作用域內,所發生的關係。而重寫是類與類之間的關係。且基類有關鍵字virtual(換句話說就是發生在繼承中的現象)

學好繼承區別這兩個概念很重要:重寫和覆蓋

區別:如果基類中沒有關鍵字virtual,那他一定是覆蓋。有關鍵字virtual一定是重寫。記得重寫和覆蓋都是對於子類對於父類來說的。

我們知道過載函式與返回值型別無關,那麼重寫和覆蓋也和返回值型別無關。

一下例子區分者四個概念:

我們說過沒有virtual關鍵字且只要函式名相同就會發生將函式名相同的全覆蓋。很顯然

father->fun()被覆蓋。記住是對於子類來說father->fun()被覆蓋。

virtual int fun(int a) 很顯然基類有關鍵字virtual所以是重寫。

father->fun(); // 輸出結果,call father fun(); // 覆蓋是對子類來說的。father是分類。

father->fun(10); // 輸出結果,call son fun();   // 重寫,且要知道乙個概念。

father* father = new son;

father->fun(10);

由於c++是靜態語言,而有了virtual虛函式則變為動態的函式,所以,father->fun(10);的輸出結果會是call son fun();

father指標指向的內容並沒有變,只不過是帶有virtual關鍵字的函式替換了。這就叫動態編譯。

接著上圖:

father裡的fun()和father裡的fun(int a)  過載。

son裡的fun()和son裡的fun(int a)  過載。

father裡的函式與son裡的函式不在同一作用域內,所以不存在過載,這是類與類之間的關係,只存在覆蓋和重寫。

既然基類中有關鍵字override,就是重寫了,那為什麼還會有override關鍵字呢???

override存在的好處之一是,檢查此函式是否是真正的重寫,如果有關鍵字override而基類中沒有關鍵字virtual則會報錯。

另乙個好處,是保證其為真重寫,不存在錯誤。有了override則必須保證重寫函式引數列表一模一樣,返回值型別可以不一樣。

總結起來就是:override就是乙個重寫函式的保險。

例子:

#include using namespace std;

class father

virtual void fun(int a)

};class son:public father

virtual void fun(char a) // 沒有override

};int main(void)

輸出結果:

多型:其實上面已經用到了多型知識只是沒總結。

同一操作作用於不同的物件,可以有不同的解釋,產生不同的執行結果。在執行時,可以通過指向基類的指標,來呼叫實現派生類中的方法。

father* father = new son;

father->fun();

father father;

son son;

father = son;

father.fun();

father.fun(10);

輸出結果:

還是從記憶體的角度去分析:

father = son;雖然將father強制轉換為son但是,father所對應的記憶體並沒有改變,還是那麼大,

father father;

son son;

cout << &father << endl;

father = son;

cout << &father << endl;

總結 繼承,多型

一.不能被繼承的父類成員 1.private 2.子類與父類不在同包,使用預設訪問許可權的成員。3.構造方法。二.訪問許可權 從小到大 private 私有的 friendly 預設 protected 受保護的 public 公有的 三.方法重寫規則 1.方法名相同。2.引數列表相同。3.返回值型...

繼承和多型

物件導向程式設計時有乙個非常重要的原則 write once only once 編寫一次,且僅編寫一次 如果沒有繼承這種機制我們可能要重複寫很多 下面來看一下繼承 一 繼承 1 子類如果繼承父類必須使用extends這個關鍵字 2 子類呼叫父類的構造方法使用super關鍵字,也可以通過super來...

繼承和多型

物件導向程式設計時有乙個非常重要的原則 write once only once 編寫一次,且僅編寫一次 如果沒有繼承這種機制我們可能要重複寫很多 下面來看一下繼承 一 繼承 1 子類如果繼承父類必須使用extends這個關鍵字 2 子類呼叫父類的構造方法使用super關鍵字,也可以通過super來...