返回目录 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分别属于三个类:
三个words相互独立,若是咱们直接使用words,是最外层的LuckyCharm类的words,其父类的words必须使用类名加上域做用符进行调用。
lycm.speak(); // 调用锦鲤对象的speak函数 lycm.Brocade::speak(); // 调用锦鲤对象的父类锦缎对象的speak函数 lycm.Carp::speak(); // 调用锦鲤对象的父类鲤鱼对象的speak函数
words是私有成员,没法直接访问,这里公有的speak()函数能够看出这一特色。
咱们能够在锦鲤类中使用本类、锦缎类和鲤鱼类的资源。
返回目录 1 面向对象技术
上一节 1.7 cpp中类的常见特性
下一节 1.9 多态
参考资料: