49課 多型的基本概念

脆香米送給你發表於2020-10-08

第四十九課 多型的概念和意義

1.函式重寫回顧

父類中被重寫的函式依然會繼承給子類
子類中重寫的函式將覆蓋父類中的函式
通過作用域分辨符(::)可以訪問到父類中的函式
在這裡插入圖片描述

2.多型的概念和意義

物件導向中期望的行為
根據實際的物件型別盤算如何呼叫重寫函式
父類指標(引用)指向
父類物件則呼叫父類中定義的函式
子類物件則呼叫子類中定義的重寫函式
物件導向中的多型的概念
根據實際的物件型別決定函式呼叫的具體目標
同樣的呼叫語句在實際執行時由多種不同的表現形態
在這裡插入圖片描述
C++語言直接支援多型的概念
通過使用virtual關鍵字對多型進行支援
被virtual宣告的函式被重寫後具有多型特性
被virtual宣告的函式叫做虛擬函式

49-1 多型的初體驗

#include <iostream>
#include <string>
using namespace std;
class Parent
{
public:
    virtual void print()
    {
        cout << "I'm Parent." << endl;
    }
};
class Child : public Parent
{
public:
    virtual void print()
    {
        cout << "I'm Child." << endl;
    }
};
void how_to_print(Parent* p)
{
    p->print();     // 展現多型的行為
}
int main()
{
    Parent p;
    Child c;
    how_to_print(&p);    // Expected to print: I'm Parent.
    how_to_print(&c);    // Expected to print: I'm Child.
    return 0;
}
執行結果
I'm Parent.
I'm Child.

多型的意義
在程式執行過程中展現出動態的特性
函式重寫必須多型實現,否則沒有意義
多型是物件導向元件化程式設計的基礎特性
理論中的概念
靜態聯編
在程式的編譯期間就能確定具體的函式呼叫
如:函式過載
動態聯編—多型
在程式實際執行後才能確定具體的函式呼叫
如:函式重寫

49-2 動態聯編與靜態聯編

#include <iostream>
#include <string>
using namespace std;
class Parent
{
public:
    virtual void func()
    {
        cout << "void func()" << endl;
    }
    virtual void func(int i)
    {
        cout << "void func(int i) : " << i << endl;
    }
    virtual void func(int i, int j)
    {
        cout << "void func(int i, int j) : " << "(" << i << ", " << j << ")" << endl;
    }
}:
class Child : public Parent
{
public:
    void func(int i, int j)
    {
        cout << "void func(int i, int j) : " << i + j << endl;
    }
    void func(int i, int j, int k)
    {
        cout << "void func(int i, int j, int k) : " << i + j + k << endl;
    }
};
void run(Parent* p)
{
    p->func(1, 2);     // Showing polymorphic characteristics
                       // Dynamic binding
}
int main()
{
    Parent p;
    p.func();         // Static binding
    p.func(1);        // Static binding
    p.func(1, 2);     // Static binding
    cout << endl;
    Child c;
    c.func(1, 2);     // Static binding
    cout << endl;
    run(&p);
    run(&c);
    return 0;
}
執行結果
void func()
void func(int i) : 1
void func(int i, int j) : (1, 2)
void func(int i, int j) : 3
void func(int i, int j) : (1, 2)
void func(int i, int j) : 3

49-3 江湖恩怨

#include <iostream>
#include <string>
using namespace std;
class Boss
{
public:
    int fight()
    {
        int ret = 10;
        cout << "Boss::fight() : " << ret << endl
        return ret;
    }
};
class Master
{
public:
    virtual int eightSwordKill()
    {
        int ret = 8;
        cout << "Master::eightSwordKill() : " << ret << endl;
        return ret;
    }
};
class NewMaster : public Master
{
public:
    int eightSwordKill()
    {
        int ret = Master::eightSwordKill() * 2;
        cout << "NewMaster::eightSwordKill() : " << ret << endl;
        return ret;
    }
};
void field_pk(Master* master, Boss* boss)
{
    int k = master->eightSwordKill();
    int b = boss->fight();
    if( k < b )
    {
        cout << "Master is killed..." << endl;
    }
    else
    {
        cout << "Boss is killed..." << endl;
    }
}
int main()
{
    Master master;
    Boss boss;
    cout << "Master vs Boss" << endl;
    field_pk(&master, &boss);
    cout << "NewMaster vs Boss" << endl;
    NewMaster newMaster;
    field_pk(&newMaster, &boss);
    return 0;
}
執行結果
Master vs Boss
Master::eightSwordKill() : 8
Boss::fight() : 10
Master is killed...
NewMaster vs Boss
Master::eightSwordKill() : 8
NewMaster::eightSwordKill() : 16
Boss::fight() : 10
Boss is killed...

小結
函式重寫只可能發生在父類與子類之間
根據實際物件的型別確定呼叫的具體函式
virtual關鍵字是C++中支援多型的唯一方式
被重寫的虛擬函式可表現出多型的特性

相關文章