自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

學(xué)不會(huì) C++ 多態(tài)?那你可能永遠(yuǎn)只是個(gè)代碼搬運(yùn)工!

開發(fā) 前端
隨著機(jī)器人種類的增加,主程序變得越來越龐大,代碼的擴(kuò)展性和維護(hù)性也受到影響。更糟的是,如果程序中的多個(gè)地方都調(diào)用performTask(),每次新增機(jī)器人類型時(shí),都需要在多個(gè)地方進(jìn)行修改。

大家好,我是小康。今天我們要一起走進(jìn) C++ 的世界,探索一個(gè)非常強(qiáng)大的概念——多態(tài)。

在一個(gè)被代碼環(huán)繞的程序員村莊里,三位年輕的程序員:小李、小張和小王,正忙于解決一個(gè)全新的問題——"如何設(shè)計(jì)一個(gè)可以執(zhí)行各種任務(wù)的機(jī)器人?" 無論是清潔、烹飪,還是修理,他們都希望這個(gè)機(jī)器人能夠根據(jù)不同的需求,自如地切換任務(wù)。正當(dāng)他們感到困惑時(shí),多態(tài)的概念為他們帶來了答案。

小李的初步設(shè)計(jì):讓機(jī)器人執(zhí)行任務(wù)

小李首先提出了一個(gè)簡單的想法:設(shè)計(jì)一個(gè)Robot 基類,所有機(jī)器人繼承自這個(gè)基類,并通過performTask() 方法來執(zhí)行各自的任務(wù)。他的初步代碼如下:

class Robot {
public:
    void performTask() {
        cout << "Robot is performing a general task!" << endl;
    }
};

這個(gè)設(shè)計(jì)看起來一切順利,每個(gè)機(jī)器人只需要繼承Robot 基類,并實(shí)現(xiàn)自己的performTask() 方法。于是,小李創(chuàng)建了兩個(gè)子類:CleaningRobot(掃地機(jī)器人)和CookingRobot(做飯機(jī)器人):

class CleaningRobot : public Robot {
public:
    void performTask() {
        cout << "Cleaning robot is sweeping the floor!" << endl;
    }
};

class CookingRobot : public Robot {
public:
    void performTask() {
        cout << "Cooking robot is making dinner!" << endl;
    }
};

一開始,小李覺得這樣的設(shè)計(jì)非常完美。每個(gè)子類都能根據(jù)自己的職責(zé)實(shí)現(xiàn)performTask() 方法。但很快,他就發(fā)現(xiàn)了一個(gè)問題……

問題:修改與擴(kuò)展的困難

隨著小李設(shè)計(jì)的機(jī)器人種類越來越多,他開始意識(shí)到,若要增加新的機(jī)器人類型(比如WashingRobot 或RepairRobot),每次都需要手動(dòng)修改主程序,增加新機(jī)器人的實(shí)例,并調(diào)用它們的performTask() 方法。

舉個(gè)例子,如果新增了RepairRobot,主程序就可能需要改成這樣:

int main() {
    CleaningRobot cleaningRobot;
    CookingRobot cookingRobot;
    RepairRobot repairRobot;  // 新增機(jī)器人

    cleaningRobot.performTask();
    cookingRobot.performTask();
    repairRobot.performTask();  // 新增的任務(wù)

    return 0;
}

隨著機(jī)器人種類的增加,主程序變得越來越龐大,代碼的擴(kuò)展性和維護(hù)性也受到影響。更糟的是,如果程序中的多個(gè)地方都調(diào)用performTask(),每次新增機(jī)器人類型時(shí),都需要在多個(gè)地方進(jìn)行修改。

小李感嘆道:“如果能有一種方法,避免每次修改主程序,而是讓系統(tǒng)根據(jù)需要自動(dòng)適應(yīng)新增的機(jī)器人類型,那該有多好!”

小張的點(diǎn)撥:為什么引入多態(tài)

小李苦思冥想后,終于提出了自己的擔(dān)憂:“每次我們新增一種機(jī)器人類型,主程序都需要修改,這樣不太靈活。而且隨著機(jī)器人種類的增加,代碼也會(huì)變得越來越復(fù)雜?!?/p>

小張點(diǎn)了點(diǎn)頭,笑著說:“你提到的問題正是傳統(tǒng)繼承設(shè)計(jì)的局限性。在你目前的設(shè)計(jì)中,主程序必須知道每個(gè)具體的機(jī)器人類型,這樣就增加了代碼之間的耦合度。每當(dāng)增加新的機(jī)器人時(shí),不得不修改主程序。其實(shí),多態(tài)可以幫助我們解決這個(gè)問題。”

小李有些疑惑:“那多態(tài)和繼承的區(qū)別到底是什么?繼承不是讓子類擁有父類的功能嗎?為什么說單靠繼承不夠呢?”

小張耐心地解釋道:“繼承確實(shí)讓子類繼承了父類的功能,但它并沒有解決代碼依賴具體類型的問題。具體來說,通過繼承,程序仍然需要顯式地知道每個(gè)子類的類型。而多態(tài)的本質(zhì)是:通過基類指針或引用,你可以在運(yùn)行時(shí)根據(jù)對(duì)象的實(shí)際類型,自動(dòng)調(diào)用正確的子類方法。也就是說,主程序不需要關(guān)心對(duì)象的具體類型,而只關(guān)心一個(gè)統(tǒng)一的接口?!?/p>

對(duì)比:普通繼承與多態(tài)

擴(kuò)展性與維護(hù)性

小張舉了一個(gè)例子來幫助小李理解。首先,他展示了沒有多態(tài)時(shí)的設(shè)計(jì):

int main() {
    CleaningRobot cleaningRobot;
    CookingRobot cookingRobot;
    RepairRobot repairRobot;  // 新增機(jī)器人

    cleaningRobot.performTask();
    cookingRobot.performTask();
    repairRobot.performTask(); // 每次新增任務(wù)時(shí),都需要修改主程序
}

小張解釋道:“看,沒多態(tài)時(shí),每次我們新增一個(gè)機(jī)器人類型(例如RepairRobot),就需要修改主程序,手動(dòng)添加新機(jī)器人的實(shí)例,并調(diào)用其performTask() 方法。這使得代碼耦合度變高,也讓維護(hù)和擴(kuò)展變得困難?!?/p>

接著,小張展示了使用多態(tài)后的設(shè)計(jì):

class RepairRobot : public Robot {
public:
    void performTask() {
        cout << "Repair robot is fixing things!" << endl;
    }
};

int main() {
    Robot* robot1 = new CleaningRobot();
    Robot* robot2 = new CookingRobot();
    Robot* robot3 = new RepairRobot();  // 新增機(jī)器人

    robot1->performTask();
    robot2->performTask();
    robot3->performTask();

    delete robot1;
    delete robot2;
    delete robot3;
    return 0;
}

“通過多態(tài),你看,”小張繼續(xù)說道,“我們幾乎不需要修改主程序,只需新增一個(gè)RepairRobot 類并實(shí)現(xiàn)它自己的performTask() 方法,程序會(huì)自動(dòng)根據(jù)對(duì)象的實(shí)際類型來選擇調(diào)用對(duì)應(yīng)的performTask() 方法。這樣,主程序和機(jī)器人類型之間的依賴就大大減少了,擴(kuò)展性和維護(hù)性也得到了提升?!?/p>

統(tǒng)一接口,解耦主程序

為了進(jìn)一步強(qiáng)調(diào)多態(tài)的優(yōu)勢,小張又講解了如何通過統(tǒng)一接口減少代碼冗余。沒有多態(tài)時(shí),我們可能需要為每種機(jī)器人類型編寫不同的函數(shù):

void doSomethingWithRobot(CleaningRobot& robot) {
    robot.performTask();
}

void doSomethingWithRobot(CookingRobot& robot) {
    robot.performTask();
}

“每新增一種機(jī)器人類型,我們就要寫一個(gè)新的函數(shù),”小張說,“這樣不僅讓代碼變得冗長,也導(dǎo)致維護(hù)起來更加麻煩。”

而使用多態(tài)后,情況就變得簡單了。只需要寫一個(gè)函數(shù):

void doSomethingWithRobot(Robot* robot) {
    robot->performTask();
}

“看,使用多態(tài)后,”小張繼續(xù)說道,“無論新增多少種機(jī)器人類型,主程序都不需要修改。主程序和具體實(shí)現(xiàn)解耦,代碼更簡潔,也更易于維護(hù)。”

注意:無論是繼承還是多態(tài),新增一個(gè)機(jī)器人時(shí),都需要?jiǎng)?chuàng)建一個(gè)新類并實(shí)現(xiàn)相應(yīng)的接口。區(qū)別在于:使用繼承時(shí),主程序必須顯式地添加新機(jī)器人的實(shí)例并調(diào)用其方法,而使用多態(tài)后,主程序幾乎不需要做任何修改,新增的機(jī)器人類型可以自動(dòng)適配。

實(shí)現(xiàn)多態(tài):關(guān)鍵點(diǎn)

最后,小張總結(jié)道:“要實(shí)現(xiàn)多態(tài),關(guān)鍵在于將基類的performTask() 方法聲明為virtual,這樣程序就可以在運(yùn)行時(shí)正確調(diào)用子類的重寫方法?!?/p>

class Robot {
public:
    virtual void performTask() {
        cout << "Robot is performing a general task!" << endl;
    }
    virtual ~Robot() { }  // 確?;愑刑撐鰳?gòu)函數(shù)
};

class CleaningRobot : public Robot {
public:
    void performTask()  {
        cout << "Cleaning robot is sweeping the floor!" << endl;
    }
};

class CookingRobot : public Robot {
public:
    void performTask() {
        cout << "Cooking robot is making dinner!" << endl;
    }
};

通過virtual 關(guān)鍵字,基類的performTask() 方法就成了虛函數(shù),子類實(shí)現(xiàn)的performTask() 方法將在運(yùn)行時(shí)被正確調(diào)用。這就是多態(tài)的實(shí)現(xiàn),它讓程序的擴(kuò)展和維護(hù)變得更加靈活和高效。

小王的補(bǔ)充: 如何使用多態(tài) ?

通過前面的講解,你已經(jīng)了解了多態(tài)的基本概念:通過基類指針,我們可以在運(yùn)行時(shí)動(dòng)態(tài)選擇調(diào)用哪個(gè)子類的方法。小王補(bǔ)充道:“多態(tài)的關(guān)鍵就在于,通過基類指針或引用,我們可以調(diào)用統(tǒng)一的接口,而不需要關(guān)心具體的子類實(shí)現(xiàn)?!?/p>

示例代碼:

int main() {
    Robot* robot1 = new CleaningRobot();
    Robot* robot2 = new CookingRobot();

    robot1->performTask();  // 輸出:Cleaning robot is sweeping the floor!
    robot2->performTask();  // 輸出:Cooking robot is making dinner!

    delete robot1;
    delete robot2;
    return 0;
}

在這個(gè)示例中,robot1 和robot2 分別指向CleaningRobot 和CookingRobot 類型的對(duì)象。通過基類指針Robot*,我們調(diào)用performTask() 方法時(shí),程序會(huì)自動(dòng)根據(jù)實(shí)際的對(duì)象類型選擇正確的方法實(shí)現(xiàn)。即使我們不明確指定子類類型,程序依然能正確地執(zhí)行不同的任務(wù)。

這就是多態(tài)的優(yōu)勢:主程序不需要關(guān)心每個(gè)機(jī)器人對(duì)象的具體類型,它只需要通過基類接口來進(jìn)行調(diào)用。通過這種方式,程序與具體的子類解耦,極大地提高了代碼的靈活性和可維護(hù)性。

小李的收獲:多態(tài)的優(yōu)勢

小李總結(jié)了多態(tài)帶來的幾個(gè)關(guān)鍵優(yōu)勢:

  1. 統(tǒng)一接口:通過基類接口調(diào)用方法,主程序無需關(guān)心具體的子類類型。無論是CleaningRobot 還是CookingRobot,都能通過相同的接口來執(zhí)行任務(wù),簡化了代碼。
  2. 擴(kuò)展性強(qiáng):當(dāng)我們需要新增一個(gè)機(jī)器人類型時(shí),只需創(chuàng)建一個(gè)新的子類,并實(shí)現(xiàn)必要的方法,主程序的代碼無需修改。程序會(huì)自動(dòng)適應(yīng)新增的子類,極大提高了代碼的擴(kuò)展性和靈活性。

總結(jié):多態(tài)的魔力

通過小李的探索和小張、小王的補(bǔ)充,我們已經(jīng)掌握了多態(tài)的基本概念:通過基類指針或引用,程序能夠在運(yùn)行時(shí)自動(dòng)選擇調(diào)用不同子類的方法。這不僅讓程序的結(jié)構(gòu)更加簡潔,還極大地提升了代碼的靈活性和可擴(kuò)展性。

正如我們所看到的,無論機(jī)器人種類如何增加,程序的主體結(jié)構(gòu)幾乎不需要修改,新增的機(jī)器人只需要實(shí)現(xiàn)基類定義的接口,程序便能自動(dòng)適配。這種特性使得多態(tài)成為了實(shí)現(xiàn)代碼復(fù)用和解耦的強(qiáng)大工具,幫助我們更輕松地應(yīng)對(duì)不斷變化的需求。

這正是多態(tài)的魅力所在:它讓我們的代碼變得更加模塊化、易于擴(kuò)展和維護(hù)。在下篇文章中,我們將進(jìn)一步探討多態(tài)的實(shí)現(xiàn)原理,揭秘它是如何在編譯和運(yùn)行時(shí)發(fā)揮作用的。

責(zé)任編輯:武曉燕 來源: 跟著小康學(xué)編程
相關(guān)推薦

2022-06-01 09:50:21

Skopeo搬運(yùn)工鏡像

2010-01-12 18:27:58

C++代碼

2011-05-23 10:15:55

2014-01-16 16:58:06

cdn

2009-06-29 10:20:25

搬運(yùn)工軟件工程師

2024-12-25 09:25:38

2022-03-27 22:07:35

元宇宙虛擬人IBM

2009-06-05 11:15:29

3G無線互聯(lián)網(wǎng)

2011-07-15 00:47:13

C++多態(tài)

2020-09-01 14:17:03

WindowsDefender微軟

2010-02-03 10:50:33

C++多態(tài)

2019-05-30 15:20:04

webpack前端開發(fā)

2019-02-12 17:11:03

云計(jì)算IaaSPaaS

2024-04-01 06:21:10

2011-04-06 08:57:07

C++java多態(tài)

2022-02-25 15:59:20

人工智能

2010-11-22 16:01:08

C++多態(tài)

2010-02-05 16:07:52

C++多態(tài)覆蓋

2011-04-12 10:40:04

C++多態(tài)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)