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):对象

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