C++中實(shí)現(xiàn)接口繼承與實(shí)現(xiàn)繼承的方法及它們的區(qū)別
概念
在 C++ 中,接口繼承和實(shí)現(xiàn)繼承是兩種不同的繼承方式,它們?cè)谠O(shè)計(jì)模式、代碼復(fù)用和多態(tài)性方面有著不同的應(yīng)用。下面將分別解釋這兩者的概念、實(shí)現(xiàn)方式及其區(qū)別。
接口繼承
接口繼承指的是只繼承類(lèi)的接口(即公共的成員函數(shù)聲明)而不實(shí)現(xiàn)這些函數(shù)。通常通過(guò)純虛函數(shù)來(lái)實(shí)現(xiàn)。這樣做的目的是約定一個(gè)行為規(guī)范,而具體的實(shí)現(xiàn)則留給派生類(lèi)去完成。
示例:
#include <iostream> // 定義一個(gè)接口 class Drawable { public: virtual void draw() const = 0; // 純虛函數(shù) virtual ~Drawable() {} // 虛析構(gòu)函數(shù)以保證正確的析構(gòu) }; class Circle : public Drawable { public: void draw() const override { std::cout << "Drawing a circle." << std::endl; } }; class Square : public Drawable { public: void draw() const override { std::cout << "Drawing a square." << std::endl; } }; void render(const Drawable& shape) { shape.draw(); // 調(diào)用接口的實(shí)現(xiàn) } int main() { Circle circle; Square square; render(circle); // 輸出: Drawing a circle. render(square); // 輸出: Drawing a square. return 0; }
輸出
Drawing a circle.
Drawing a square.
代碼解析
接口定義
class Drawable { public: virtual void draw() const = 0; // 純虛函數(shù) virtual ~Drawable() {} // 虛析構(gòu)函數(shù)以保證正確的析構(gòu) };
- 類(lèi) Drawable 是一個(gè)接口類(lèi),使用大寫(xiě)字母開(kāi)頭的名稱(chēng)有助于表明它是一個(gè)接口。
- virtual void draw() const = 0; 聲明了一個(gè)純虛函數(shù) draw(),這意味著 Drawable 類(lèi)沒(méi)有實(shí)現(xiàn)此函數(shù),任何派生類(lèi)必須實(shí)現(xiàn)這個(gè)函數(shù)。這里的 = 0 表示這是一個(gè)純虛函數(shù),任何包含它的類(lèi)都被視為抽象類(lèi),無(wú)法直接實(shí)例化。
- virtual ~Drawable() {} 是一個(gè)虛析構(gòu)函數(shù),允許使用基類(lèi)指針刪除派生類(lèi)實(shí)例時(shí)確保資源正確釋放。這是接口設(shè)計(jì)的良好實(shí)踐。
- 實(shí)現(xiàn)接口的派生類(lèi)
class Circle : public Drawable { public: void draw() const override { std::cout << "Drawing a circle." << std::endl; } };
- class Circle : public Drawable 表示 Circle 類(lèi)繼承自 Drawable 接口,派生類(lèi)必須實(shí)現(xiàn)所有的純虛函數(shù)。
- void draw() const override 這是對(duì)基類(lèi) Drawable 中 draw() 的實(shí)現(xiàn)。通過(guò) override 關(guān)鍵字指示這是對(duì)基類(lèi)虛函數(shù)的重寫(xiě)。
- 在 draw() 方法中,我們使用 std::cout 輸出 “Drawing a circle.”。
class Square : public Drawable { public: void draw() const override { std::cout << "Drawing a square." << std::endl; } };
- Square 類(lèi)實(shí)現(xiàn)與 Circle 類(lèi)類(lèi)似,只是輸出的信息不同。它同樣繼承了 Drawable 接口并實(shí)現(xiàn) draw() 方法。
- 渲染函數(shù)
void render(const Drawable& shape) { shape.draw(); // 調(diào)用接口的實(shí)現(xiàn) }
- render 函數(shù) 接受一個(gè)常量引用類(lèi)型的 Drawable 對(duì)象,這允許傳入任何實(shí)現(xiàn)了 Drawable 接口的對(duì)象。
- 在函數(shù)內(nèi)部調(diào)用 shape.draw(),通過(guò)多態(tài)的機(jī)制,這將調(diào)用傳入對(duì)象的具體 draw() 實(shí)現(xiàn),打印出形狀信息。
- 主函數(shù)
int main() { Circle circle; Square square; render(circle); // 輸出: Drawing a circle. render(square); // 輸出: Drawing a square. return 0; }
- Circle circle; 和 Square square; 創(chuàng)建了 Circle 和 Square 對(duì)象。
- render(circle); 和 render(square); 調(diào)用了 render 函數(shù),分別傳入 circle 和 square 對(duì)象。
- 由于 render 函數(shù)使用了接口類(lèi)型 Drawable 的引用,因此可以通過(guò)多態(tài)機(jī)制實(shí)現(xiàn)適當(dāng)?shù)暮瘮?shù)調(diào)用。
關(guān)鍵點(diǎn)
- Drawable 類(lèi)是一個(gè)接口,它定義了一個(gè)純虛函數(shù) draw()。
- Circle 和 Square 類(lèi)實(shí)現(xiàn)了接口,重寫(xiě)了 draw() 函數(shù)。
- 可以通過(guò)接口類(lèi)型的引用或指針來(lái)實(shí)現(xiàn)多態(tài)。
總結(jié)
- 接口繼承的靈活性:通過(guò)使用抽象類(lèi)(接口),我們可以定義統(tǒng)一的行為規(guī)范(draw())。不同的實(shí)現(xiàn)類(lèi)(Circle 和 Square)可以各自實(shí)現(xiàn)該接口的函數(shù),從而提供特定的行為。這種設(shè)計(jì)模式使得代碼的可擴(kuò)展性和可維護(hù)性得以提高。
- 多態(tài)性:使用指向接口類(lèi)的指針或引用可以實(shí)現(xiàn)多態(tài),允許我們?cè)诓恍薷?render 函數(shù)的情況下輕松添加新的形狀類(lèi)。
- 虛構(gòu)造和釋放:使用虛析構(gòu)函數(shù)確保在刪除基類(lèi)指針時(shí)能夠正確地調(diào)用派生類(lèi)的析構(gòu)函數(shù),從而避免內(nèi)存泄露。
實(shí)現(xiàn)繼承
實(shí)現(xiàn)繼承指的是繼承一個(gè)類(lèi)的完整實(shí)現(xiàn),而不僅僅是接口。這意味著子類(lèi)不僅可以使用父類(lèi)的方法和屬性,還可以訪問(wèn)和重用父類(lèi)的實(shí)現(xiàn)。這種方式通常在需要共享代碼的場(chǎng)景中使用。
示例:
#include <iostream> // 基類(lèi) class Shape { public: void setPosition(int x, int y) { m_x = x; m_y = y; } protected: int m_x, m_y; // 保護(hù)的成員變量 }; class Circle : public Shape { public: void draw() { std::cout << "Drawing a circle at (" << m_x << ", " << m_y << ")." << std::endl; } }; class Square : public Shape { public: void draw() { std::cout << "Drawing a square at (" << m_x << ", " << m_y << ")." << std::endl; } }; int main() { Circle circle; circle.setPosition(10, 20); circle.draw(); // 輸出: Drawing a circle at (10, 20). Square square; square.setPosition(30, 40); square.draw(); // 輸出: Drawing a square at (30, 40). return 0; }
輸出
Drawing a circle at (10, 20).
Drawing a square at (30, 40).
代碼解析
基類(lèi)定義
class Shape { public: void setPosition(int x, int y) { m_x = x; m_y = y; } protected: int m_x, m_y; // 保護(hù)的成員變量 };
- 基類(lèi) Shape 是一個(gè)描述形狀的類(lèi)。
- setPosition(int x, int y) 方法 是一個(gè)公共方法,用于設(shè)置形狀的坐標(biāo)。通過(guò)設(shè)置 m_x 和 m_y 成員變量,基類(lèi)提供了一個(gè)基本的行為。
- protected 修飾符 表示 m_x 和 m_y 只能在 Shape 類(lèi)及其派生類(lèi)中訪問(wèn)。這賦予了派生類(lèi)對(duì)這些成員的訪問(wèn)權(quán)限,允許它們讀取和修改位置。
- 派生類(lèi)定義
class Circle : public Shape { public: void draw() { std::cout << "Drawing a circle at (" << m_x << ", " << m_y << ")." << std::endl; } };
- class Circle : public Shape 表示 Circle 類(lèi)派生自 Shape 類(lèi),繼承了所有公共和保護(hù)成員。
- void draw() 方法 在 Circle 類(lèi)中實(shí)現(xiàn),負(fù)責(zé)輸出當(dāng)前圓形的坐標(biāo)信息。
class Square : public Shape { public: void draw() { std::cout << "Drawing a square at (" << m_x << ", " << m_y << ")." << std::endl; } };
- class Square : public Shape 類(lèi)似于 Circle 類(lèi),Square 也繼承自 Shape 類(lèi)。
- draw() 方法負(fù)責(zé)輸出當(dāng)前正方形的坐標(biāo)信息。
- 主函數(shù)實(shí)現(xiàn)
int main() { Circle circle; circle.setPosition(10, 20); circle.draw(); // 輸出: Drawing a circle at (10, 20). Square square; square.setPosition(30, 40); square.draw(); // 輸出: Drawing a square at (30, 40). return 0; }
- 在 main() 函數(shù)中,首先創(chuàng)建了一個(gè) Circle 對(duì)象。
- circle.setPosition(10, 20); 調(diào)用基類(lèi)的 setPosition 方法設(shè)置圓形的坐標(biāo)。
- circle.draw(); 調(diào)用 Circle 類(lèi)的 draw() 方法輸出圓形的坐標(biāo)。
- 類(lèi)似的,對(duì) Square 類(lèi)進(jìn)行相同的操作,設(shè)置其位置并輸出。
關(guān)鍵點(diǎn)
- Shape 類(lèi)提供了一些具體的實(shí)現(xiàn),比如 setPosition() 方法來(lái)設(shè)置形狀的位置。
- Circle 和 Square 類(lèi)繼承自 Shape,它們可以使用 Shape 中已實(shí)現(xiàn)的方法。
- 子類(lèi)可以重用父類(lèi)的代碼,也可以擴(kuò)展其功能。
總結(jié)
- 實(shí)現(xiàn)繼承的作用:
- Circle 和 Square 類(lèi)繼承自 Shape 類(lèi),能夠重用基類(lèi)的代碼,特別是 setPosition 方法,避免了重復(fù)實(shí)現(xiàn)。
- 通過(guò)繼承,所有形狀類(lèi)可以共享 Shape 類(lèi)的成員和方法,簡(jiǎn)化代碼結(jié)構(gòu)。
- 訪問(wèn)控制:
- 使用 protected 修飾符允許派生類(lèi)訪問(wèn)基類(lèi)的成員變量,保持?jǐn)?shù)據(jù)的封裝性,但同時(shí)允許派生類(lèi)訪問(wèn)必要的數(shù)據(jù)。
- 良好的可擴(kuò)展性:
- 由于 Shape 類(lèi)作為基類(lèi),可以輕松添加更多形狀(例如 Triangle),只需繼承 Shape 類(lèi)并實(shí)現(xiàn) draw() 方法而不需要重復(fù)代碼。
- 多態(tài)性:
- 在這個(gè)簡(jiǎn)單的實(shí)現(xiàn)中沒(méi)有用到多態(tài)性,但可以通過(guò)把 draw() 方法聲明為虛函數(shù)和使用基類(lèi)指針或引用來(lái)增強(qiáng)多態(tài)特性,這樣可以通過(guò)基類(lèi)類(lèi)型處理不同的派生類(lèi)對(duì)象。
區(qū)別
到此這篇關(guān)于C++中如何實(shí)現(xiàn)接口繼承與實(shí)現(xiàn)繼承,以及它們的區(qū)別?的文章就介紹到這了,更多相關(guān)C++接口繼承與實(shí)現(xiàn)繼承內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
c++實(shí)現(xiàn)十進(jìn)制轉(zhuǎn)換成16進(jìn)制示例
這篇文章主要介紹了c++實(shí)現(xiàn)十進(jìn)制轉(zhuǎn)換成16進(jìn)制示例,需要的朋友可以參考下2014-05-05??C++11系列學(xué)習(xí)之Lambda表達(dá)式
這篇文章主要介紹了??C++11系列學(xué)習(xí)之Lambda表達(dá)式,C++11終于也引入了lambda表達(dá)式,lambda最早來(lái)源于函數(shù)式編程,現(xiàn)代語(yǔ)言慢慢都引入了這個(gè)語(yǔ)法,下文關(guān)于??C++11Lambda表達(dá)式相關(guān)內(nèi)容需要的小伙伴可以參考一下2022-04-04Qt中QScrollArea控件的實(shí)現(xiàn)
QScrollArea是Qt框架中用于提供一個(gè)滾動(dòng)條區(qū)域,允許用戶(hù)滾動(dòng)查看比當(dāng)前可視區(qū)域更大的內(nèi)容的控件,本文主要介紹了Qt中QScrollArea控件的實(shí)現(xiàn),感興趣的可以了解一下2025-04-04基于C++詳解數(shù)據(jù)結(jié)構(gòu)(附帶例題)
數(shù)據(jù)結(jié)構(gòu)作為每一個(gè)IT人不可回避的問(wèn)題,本文基于C++編寫(xiě),下面這篇文章主要給大家介紹了關(guān)于數(shù)據(jù)結(jié)構(gòu)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-06-06C語(yǔ)言實(shí)現(xiàn)CRC校驗(yàn)算法的示例詳解
CRC(Cyclic Redundancy Check,循環(huán)冗余校驗(yàn))是一種常用的錯(cuò)誤檢測(cè)技術(shù),用于驗(yàn)證數(shù)據(jù)在傳輸或存儲(chǔ)過(guò)程中是否發(fā)生了錯(cuò)誤,本文主要介紹了C語(yǔ)言如何實(shí)現(xiàn)CRC校驗(yàn)算法,需要的可以參考一下2023-08-08C++實(shí)現(xiàn)一鍵關(guān)閉桌面的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何利用C++實(shí)現(xiàn)一鍵關(guān)閉桌面的功能,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以了解一下2023-07-07C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)算法基礎(chǔ)之循環(huán)隊(duì)列示例
這篇文章主要為大家介紹了C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)算法基礎(chǔ)之循環(huán)隊(duì)列,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06