1.8 繼承

1.8 繼承


返回目錄 1 面向對象技術
上一節 1.7 cpp中類的常見特性
下一節 1.9 多態ios


概念:c++

繼承(英語:inheritance)是 面向對象軟件技術當中的一個概念。

若是一個類別A「繼承自」另外一個類別B,就把這個A稱爲「B的子類別」,而把B稱爲「A的父類別」也能夠稱「B是A的超類」。編程

介紹:segmentfault

繼承可使得子類別具備父類別的各類屬性和方法,而不須要再次編寫相同的代碼。

在令子類別繼承父類別的同時,能夠從新定義某些屬性,並重寫某些方法,即覆蓋父類別的原有屬性和方法,使其得到與父類別不一樣的功能。編程語言

另外,爲子類別追加新的屬性和方法也是常見的作法。函數

通常靜態的面向對象編程語言,繼承屬於靜態的,意即在子類別的行爲在編譯期就已經決定,沒法在執行期擴充。this

特色:設計

基類成員 public protected private 不可訪問
公有繼承 public protected 不可訪問 不可訪問
保護繼承 protected protected 不可訪問 不可訪問
私有繼承 private private 不可訪問 不可訪問

單繼承

接下來舉個簡單的單繼承例子:code

源代碼

/* Extends.cpp,這是個單繼承實例 */
#include <iostream>
#include <string>

/* 這個是基類,或者叫父類 */
class Animal
{
protected: // 保護類型,只能被本身或者本身的子類調用
    std::string name;
    std::string getSex() const; // 獲取性別,const限制函數不能修改數據成員
    int getAge() const; // 獲取年齡
private:
    std::string sex; // 性別
    int age; // 年齡
public:
    Animal(std::string name_l, std::string sex_l, int age_l)
        :name(name_l), sex(sex_l), age(age_l){} // 能夠用這種方式爲數據成員賦值
    ~Animal()
    {
        /* 或者直接在類中實現函數 */
    }
};

std::string Animal::getSex() const
{
    return sex; // 返回性別
}

int Animal::getAge() const
{
    return age; // 返回年齡
}

/* 這個叫派生類,或者叫子類 */
class Cat: public Animal
{
private:
    std::string words; // 存儲叫聲
public:
    Cat(std::string name_l, std::string sex_l, int age_l, std::string words_l)
        :Animal(name_l, sex_l, age_l), words(words_l){}; // 子類在構造函數中須要調用父類構造函數,除非父類有無參構造函數
    ~Cat(){};
    void speak() const; // 輸出一段話
};

void Cat::speak() const
{
    std::cout << "我叫";
    std::cout << name << std::endl;
    std::cout << "性別是";
    // std::cout << sex << std::endl; // 不容許直接訪問基類的私有成員
    std::cout << getSex() << std::endl; // 能夠訪問基類保護成員
    std::cout << "今年";
    std::cout << getAge() << "歲了" << std::endl;
    std::cout << "個人叫聲是:";
    std::cout << words <<  std::endl; // 能夠訪問本類私有成員
}

int main()
{
    Cat cat("小花", "雌", 2, "喵喵喵");
    cat.speak();
    return 0;
}

編譯運行

我叫小花
性別是雌
今年2歲了
個人叫聲是:喵喵喵

例子中,咱們建立了一個動物類,而且派生了一個貓類。對象

咱們能夠在貓類中使用到動物類的資源。

多重繼承

源代碼

/* MultipleExtends.cpp 多重繼承實例 */
#include <iostream>
#include <string>

/* 接下來的一大片都是錦緞類的範圍 */
class Brocade // 錦緞類
{
private:
    std::string words; // 錦緞的獨白
public:
    Brocade(); // 構造函數:給錦緞的獨白賦值
    ~Brocade(); // 析構函數:提示錦緞被銷燬了
    void speak(); // 錦緞說話了!!!
};

Brocade::Brocade()
{
    this->words = "我是一條錦緞";
    std::cout << "【錦緞類對象已實例化!】" << std::endl;
}

Brocade::~Brocade()
{
    std::cout << "【錦緞類對象已被銷燬!】" << std::endl;
}

void Brocade::speak()
{
    std::cout << words << std::endl;
}
/* 錦緞類結束 */

/* 鯉魚類開始 */
class Carp // 鯉魚類
{
private:
    std::string words; // 鯉魚有話說
public:
    Carp(); // 構造函數:給鯉魚有話說賦值
    ~Carp(); // 析構函數:提示鯉魚被銷燬了
    void speak(); // 固然,鯉魚也能說話。。。(我不是泡泡)
};

Carp::Carp()
{
    this->words = "我是一隻鯉魚";
    std::cout << "【鯉魚類對象已實例化!】" << std::endl;
}

Carp::~Carp()
{
    std::cout << "【鯉魚類對象已被銷燬!】" << std::endl;
}

void Carp::speak()
{
    std::cout << words << std::endl;
}
/* 鯉魚類結束 */

/* 錦鯉類開始 */
class LuckyCharm: public Brocade, public Carp // 同時繼承了錦緞和鯉魚
{
private:
    std::string words; // 錦鯉的竊竊私語
public:
    LuckyCharm(std::string words_l):words(words_l)
    {
        std::cout << "【錦鯉類對象已實例化!】" << std::endl;
    };
    ~LuckyCharm();
    void speak();
};

LuckyCharm::~LuckyCharm()
{
    std::cout << "【錦鯉類對象已被銷燬!】" << std::endl;
}

void LuckyCharm::speak()
{
    std::cout << words << std::endl;
}

/* 錦鯉類結束 */


int main()
{

{
    LuckyCharm lycm("錦鯉在此!誰敢不服?"); // 實例化錦鯉對象

    lycm.speak(); // 調用錦鯉對象的speak函數
    lycm.Brocade::speak(); // 調用錦鯉對象的父類錦緞對象的speak函數
    lycm.Carp::speak(); // 調用錦鯉對象的父類鯉魚對象的speak函數
}

    return 0;

}

編譯運行

【錦緞類對象已實例化!】
【鯉魚類對象已實例化!】
【錦鯉類對象已實例化!】
錦鯉在此!誰敢不服?
我是一條錦緞
我是一隻鯉魚
【錦鯉類對象已被銷燬!】
【鯉魚類對象已被銷燬!】
【錦緞類對象已被銷燬!】

這是一個簡單的例子……

先忽略掉中間三個speak語句的輸出。

【錦緞類對象已實例化!】
【鯉魚類對象已實例化!】
【錦鯉類對象已實例化!】
……
【錦鯉類對象已被銷燬!】
【鯉魚類對象已被銷燬!】
【錦緞類對象已被銷燬!】

咱們應該認識到,前三條輸出語句和後三條輸出語句分別表明着構造函數析構函數的運行,由於我在構造函數和析構函數裏寫了輸出語句。

注意:

  • 構造函數是從父類開始運行,多重繼承從最左邊一個開始,到本身這個類結束;
  • 析構函數是從本身這個類開始,而後再父類,多重繼承從最右邊一個開始,到最左邊結束。

也就是說構造和析構的順序徹底相反。

而後!

三個words分別屬於三個類:

  • LuckyCharm::words
  • Brocade::words
  • Carp::words

三個words相互獨立,若是咱們直接使用words,是最外層的LuckyCharm類的words,其父類的words必須使用類名加上域做用符進行調用。

lycm.speak(); // 調用錦鯉對象的speak函數
lycm.Brocade::speak(); // 調用錦鯉對象的父類錦緞對象的speak函數
lycm.Carp::speak(); // 調用錦鯉對象的父類鯉魚對象的speak函數

words是私有成員,沒法直接訪問,這裏公有的speak()函數能夠看出這一特色。

咱們能夠在錦鯉類中使用本類、錦緞類和鯉魚類的資源。


返回目錄 1 面向對象技術
上一節 1.7 cpp中類的常見特性
下一節 1.9 多態


參考資料:

  • 《C++程序設計》傳智播客
  • 博客園
  • CSDN
  • 百度百科
相關文章
相關標籤/搜索