C++入门(8):类的继承(1)
2016-01-04 15:16
459 查看
C++入门(8):类的继承(1)
通过继承机制,可以对现有的、可信的代码进行扩展,并应用在新的程序中。子类是从基类(父类或超类)派生出的类,形式为:
class SubClass:public(protected、private) SuperClass{...}
对象之间的关系:
1)继承:比如说“狗是一个宠物”,则可以创建一个名为 Pet(宠物)的基类,再由它派生出一个名为 Dog(狗)的子类 ,即“是一个”的关系;
2)组合: 另外一种情况,比如说“宠物有一个名字”,则可以创建一个名为 Pet(宠物)的基类,而 name(名字)应该是 Pet 类的一个组成部分,即“有一个” 的关系。
有些类与类之间存在一种组合关系,也叫聚集。
建立组合的做法是:创建一个新类,在它里面定义一个属性,而该属性是另一个类的对象;Python中也是这么做的。
对于继承,创建对象时,会先调用基类的构造器,再调用子类的构造器。因为基类必须在子类之前初始化;
与构造器情况相反,基类的析构器将在子类的最后一条语句执行完毕之后才被调用,即调用基类的析构器是最后一件事情。
这节我们主要讨论继承,下面通过举例来了解类的继承:
[code]#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; }
运行结果为:
[code]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):对象
相关文章推荐
- C语言如何 计算程序运行时间?
- GB2312中汉字字符的编码在C语言中的输出测试
- QML解析C++的QVariantList、QVariantMap
- C语言概述【重学C之一】
- c语言中同一函数下不可以重复定义变量
- 整数变换问题和N皇后问题解析(C语言)
- c语言中数组中的地址和指针的关系
- C++界面库
- 利用C++11实现一个自动注册的工厂
- C++ friend keyword
- C语言项目答辩总结
- C++ 11 可变参数宏结合可变参数模板使用!
- C++ string 用法詳解
- c++静态成员变量的使用
- 分享C++寫blueprint block的方法
- 两条未知曲线,求其最短距离
- 介绍Unreal Engine 4中的接口(Interface)使用C++和蓝图
- c++中this指针的用法小结
- 将那些对称的字符串按从小到大的顺序输 出。字符串先以长度论大小,如果长度相同,再以 ASCII 码值为排序标准。
- 将 01 串首先按长度排序,长度相同时,按 1 的个数多少进行排序, 1 的个数相同时再 按 ASCII 码值排序。