C++入門(8):類的繼承(1)

C++入門(8):類的繼承(1)

通過繼承機制,可以對現有的、可信的代碼進行擴展,並應用在新的程序中。
子類是從基類(父類或超類)派生出的類,形式爲:
class SubClass:public(protected、private) SuperClass{...}

對象之間的關係:
1)繼承:比如說“狗是一個寵物”,則可以創建一個名爲 Pet(寵物)的基類,再由它派生出一個名爲 Dog(狗)的子類 ,即“是一個”的關係;
2)組合: 另外一種情況,比如說“寵物有一個名字”,則可以創建一個名爲 Pet(寵物)的基類,而 name(名字)應該是 Pet 類的一個組成部分,即“有一個” 的關係。

有些類與類之間存在一種組合關係,也叫聚集。
建立組合的做法是:創建一個新類,在它裏面定義一個屬性,而該屬性是另一個類的對象;Python中也是這麼做的。

對於繼承,創建對象時,會先調用基類的構造器,再調用子類的構造器。因爲基類必須在子類之前初始化;
與構造器情況相反,基類的析構器將在子類的最後一條語句執行完畢之後才被調用,即調用基類的析構器是最後一件事情。

這節我們主要討論繼承,下面通過舉例來了解類的繼承:

#include <iostream>
#include <string>

class Pet{                                         //基類
    public:
        std::string name;                          //屬性

        Pet(std::string name = "pet") ;            //構造函數
        ~Pet() ;                                   //析構函數

        void eat();                                //方法
        void sleep();
        void setName(std::string name);
};

class Dog : public Pet{                            //Dog子類
    public:
        Dog();
        ~Dog();
        void bark();                               //子類Dog中的方法
};

class Cat : public Pet{                            //Cat子類
    public:
        Cat(std::string name) ;
        ~Cat();
        void climb();                              //子類Cat中的方法
};
//方法的實現
Pet::Pet(std::string name)                         //定義構造器的時候,如果有默認參數,不用寫出其初始化值 !!
    std::cout << "I am Pet's Constructor." << std::endl;
    this->name = name;
}
Pet::~Pet()
{
    std::cout << "I am Pet's Destructor." << std::endl;
}
void Pet::eat()
{
    std::cout << "This " << name << " is eating... " << std::endl;
}
void Pet::sleep()
{
    std::cout << "This " << name << " is sleeping..." << std::endl;
}
void Pet::setName(std::string name)
{
    this->name = name;
}

Dog::Dog()
{
    std::cout << "I am Dog's Constructor." << std::endl;
}
Dog::~Dog()
{
    std::cout << "I am Dog's Destructor." << std::endl; 
}
void Dog::bark()
{
    std::cout << "This " << name << " is barking..." << std::endl;
}

Cat::Cat(std::string name):Pet(name)                   //子類構造器繼承基類的構造器
{
    this->name = name;                                 //這句賦值語句不需要,實際的初始化在基類中完成
    std::cout << "I am Cat's Constructor." << std::endl;
Cat::~Cat()
{
    std::cout << "I am Cat's Destructor." << std::endl;
}
void Cat::climb()
{
    std::cout << "This " << name << " is climbing..." << std::endl;
}

int main(int argc, char** argv) {

    Pet pet;
    Dog dog;                                           //先調用一次Pet的構造器,再調用一次Dog的構造器
    Cat cat("cat");                                    //先調用一次Pet的構造器,再調用一次Cat的構造器

    dog.eat();                                         //dog沒有初始化,所以使用的是基類Pet的默認參數
    dog.setName("dog");                                //Dog類構造器沒有初始化方法,調用基類的setName方法同樣可以初始化name屬性
    dog.sleep();
    dog.bark();
    cat.climb();                                       //定義Cat的時候已經調用了構造函數初始化了
    pet.sleep() ;

    //程序結束時,依次調用類的析構器
    return 0;
}

運行結果爲:

I am Pet's Constructor.
I am Pet's Constructor.
I am Dog's Constructor.
I am Pet's Constructor.
I am Cat's Destructor.
This pet is eating...
This dog is sleeping...
This dog is barking...
This cat is climbing...
This pet is sleeping...
I am Cat's Constructor.
I am Pet's Constructor.
I am Dog's Constructor.
I am Pet's Constructor.
I am Pet's Constructor.

C++入門(7):對象

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章