当前位置: 首页 > news >正文

【继承和派生】

引入

继承是面向对象编程的核心特性之一,允许一个类(子类或派生类)基于另一个类(父类或基类)构建,继承父类的属性和方法,同时可以扩展或修改功能(构造函数不能继承)

简言之就是子类继承父类,父类派生出子类。

格式: class 子类名 : 访问修饰符 父类名
如: class ChildClass : public ParentClass

class animal {
public:string tname;int tage;
public:animal(){}animal(string name,int age) {this->tname = name;this->tage = age;}
void printInfo() {cout << "名字叫:" << this->tname << "年龄:" << this->tage << endl;}
};class dog :public animal {
public:char sex;
public:dog(){}dog(int age, string name, char sex) {this->tage = age;this->tname = name;this->sex = sex;}
};int main() {dog d1(2, "wangcai", 'm');d1.printInfo();return 0;
}

因为dog类继承了animal类,所以在dog类里面可以直接拥有animal里面的tname和tage以及printInfo,同时又可以自己添加成员变量、成员函数。

三种继承方式

在这里插入图片描述

根据自己的理解记忆,我是按着public限制最少、优先级最低、最容易被修改,protected占中位,private优先级最高。
比如子类public继承

  • 父类中访问修饰词是public时,子类也public;
  • 父类protected时,因优先级比public高,则子类不修改(仍为protected)。
    子类protected继承
  • 父类中访问修饰词是public时,子类继承的优先级更高,改成protected;
  • 父类protected时,子类也protected。
    子类private继承
  • 父类中访问修饰词是public或protected时,子类继承的优先级更高,均需要改成private;
    所有父类private成员在子类中都不能使用。
    如图,当修改printInfo的访问修饰符为private后再引用就报错了
    在这里插入图片描述

所说的子类的不同继承方式是由上文格式部分的访问修饰符决定的。
也就是圈住的部分:
在这里插入图片描述
完整代码:

class person {
public:string tname;
protected:int tage;
private:char tsex;public:person(){}
void setName(string name) {this->tname = name;}
void setAge(int age) {this->tage = age;
}void setSex( char sex) {this->tsex = sex;
}void printInfo() {cout << "名字叫:" << this->tname << "  年龄" << this->tage << endl;}
};class student :public person {};int main() {student s1;s1.setName("aaa");s1.setAge(10);s1.setSex('g');s1.printInfo();return 0;
}

在这里插入图片描述在这里插入图片描述

tage被protected修饰,在列表中没有tage,不能直接访问
在这里插入图片描述

但能在派生类(子类)中使用,只有private既不能直接访问又不能在派生类中使用。

public:person(){}person(string name, int age, char sex) :tname(name), tage(age), tsex(sex){}/*person(string name, int age, char sex) {this->tname = name;this->tage = age;this->tsex = sex;}*/

这两种(注释掉的部分和注释的上一行)带参数的构造函数效果是一样的(下面的展示就把注释的那种方法删掉了)。
完整代码:

class person {
public:string tname;
protected:int tage;
private:char tsex;public:person(){}person(string name, int age, char sex) :tname(name), tage(age), tsex(sex){}void printInfo() {cout << "名字叫:" << this->tname << "  年龄" << this->tage << endl;}
};class student :public person {};int main() {person s1("aa", 10, 'b');s1.printInfo();return 0;
}

前面提到过父类的构造函数不能继承给子类,但子类可以引用父类的构造函数。

子类可以引用父类的构造函数
方法一:
class person {
public:string tname;
protected:int tage;
private:char tsex;public:person(){}person(string name, int age, char sex) :tname(name), tage(age), tsex(sex){}void printInfo() {cout << "名字叫:" << this->tname << "  年龄" << this->tage << endl;}
};class student :public person {
public:double score;
public:student(){}//新增变量分开写student(string name, int age, char sex, double score) :person(name, age, sex), score(score){}void showInfo() {cout << "名字:" << this->tname << "年龄:" << this->tage << endl;}
};int main() {student s1;student s2("aaa",10,'a',11.1);s2.printInfo();return 0;
}
方法二:通过using来继承基类构造函数

格式: using 基类::基类;

class person {public:person(){}person(string name, int age, char sex) :tname(name), tage(age), tsex(sex){}void printInfo() {cout << "名字叫:" << this->tname << "  年龄" << this->tage << endl;}
public:string tname;
protected:int tage;
private:char tsex;
};class student :public person {
public:using person::person;student() {}student(string name, int age, char sex, double score) :person(name, age, sex), score(score) {}void showInfo() {cout << "名字:" << this->tname << "年龄:" << this->tage << endl;}
private:double score;
};int main() {student stu("aaa",10,'a',11.1);stu.printInfo();return 0;
}

这里与上面的代码只加了一行using person::person;不能体现出using的作用,需参考下面:

class person {
public:person() {}person(string name) : tname(name) {}person(string name, int age) : tname(name), tage(age) {}person(string name, int age, char sex) : tname(name), tage(age), tsex(sex) {}person(int age) : tage(age) {}// ... 更多构造函数
};class student : public person {
public:using person::person; // 一行代码继承所有5个构造函数// 只需要处理派生类特有的情况student(string name, int age, char sex, double score) : person(name, age, sex), score(score) {}
};
构造函数调用顺序

在这里插入图片描述

using namespace std;class animal {
public:animal() {cout << "call animal " << endl;}
};class monkey :public animal {
public:monkey() {cout << "call monkey " << endl;}
};int main() {monkey m1;return 9;
}

输出结果:先调用父类,后调用子类
在这里插入图片描述

  • 子类继承父类时实例化子类,如果不知道基类构造函数就用默认构造函数,没有就会报错。
    (默认构造函数无参数,所以很多时候会留一个空白的构造函数,如:people(){ }; 再自定义有参数的构造函数。)
析构函数调用顺序

在这里插入图片描述

class animal {
public:animal() {cout << "call animal " << endl;}~animal() {cout << "call ~animal " << endl;}
};class monkey :public animal {
public:monkey() {cout << "call monkey " << endl;}~monkey() {cout << "call ~monkey " << endl;}
};int main() {monkey m1;return 0;
}

输出:
在这里插入图片描述


文章转载自:

http://ZgDvC52H.zbhfs.cn
http://eYKNoWNK.zbhfs.cn
http://AhyWuKxH.zbhfs.cn
http://ssQqpQhD.zbhfs.cn
http://64uXR9xT.zbhfs.cn
http://Mfxj4qVu.zbhfs.cn
http://2nsShWms.zbhfs.cn
http://4d3AiPAP.zbhfs.cn
http://asEKzo60.zbhfs.cn
http://fQ8txlgm.zbhfs.cn
http://0KLugF5P.zbhfs.cn
http://u9Bq6XHz.zbhfs.cn
http://ToHagf2a.zbhfs.cn
http://z2x9EEDc.zbhfs.cn
http://KUJ64NTO.zbhfs.cn
http://Z6hCl2sP.zbhfs.cn
http://YEkJ3Fql.zbhfs.cn
http://BYplBRfR.zbhfs.cn
http://sh0FwLPT.zbhfs.cn
http://cabZnYTl.zbhfs.cn
http://8GZltNRR.zbhfs.cn
http://OI4PbZqY.zbhfs.cn
http://SNYU9Nrb.zbhfs.cn
http://a0jYFfaA.zbhfs.cn
http://cHOkg3PY.zbhfs.cn
http://3yIGgRZq.zbhfs.cn
http://spNMfVJ4.zbhfs.cn
http://vL0kv9rk.zbhfs.cn
http://Ih6Zxf5Z.zbhfs.cn
http://ZG6m6QxT.zbhfs.cn
http://www.dtcms.com/a/370596.html

相关文章:

  • IDEA修改系统缓存路径,防止C盘爆满
  • scikit-learn零基础配置(含python、anaconda)
  • 《sklearn机器学习——模型的持久性》joblib 和 pickle 进行模型保存和加载
  • 深入浅出 JVM 类加载器:分类、双亲委派与打破机制
  • ViGAS、RAF、DiFF-RIR论文解读
  • 《Science》神经炎症综述思路套用:从机制到跨领域研究范式
  • macOS下arm编译缺少stdint.h等问题
  • JP4-7-MyLesson后台前端(二)
  • 机器学习高级-day01-曲线拟合
  • JAVA同城打车小程序APP打车顺风车滴滴车跑腿源码微信小程序打车源码
  • CentOS系统管理:useradd命令的全面解析
  • 小智AI编译
  • 【FastDDS】Layer Transport ( 04-TCP Transport )
  • 文件操作和IO
  • leetcode LCR 159 库存管理III
  • 使用 TCMalloc 检查内存使用情况和内存泄漏
  • Altium Designer(AD24)加载License文件方法
  • 【Gigascience】时空转录组测序探索小鼠心脏发育的细胞与分子基础
  • Ubuntu:Git SSH密钥配置的完整流程
  • 智能驾驶调研
  • 【Luogu_P8118】 「RdOI R3.5」Mystery【Slope Trick】【DP】
  • SSH服务远程安全登录
  • cds序列转换为pepperl脚本详细解读及使用
  • 什么时候用no,什么时候用non,什么时候用not?
  • 2025年本体论:公理与规则的挑战与趋势
  • 发布vue项目、nginx配置及问题场景(history)
  • Netty从0到1系列之EventLoop
  • 在Ubuntu上配置Nginx实现开机自启功能
  • 智慧灌区系统:科技赋能,让农田灌溉更智能、更高效、更可持续
  • 第2课:环境搭建:基于DeepSeek API的开发环境配置