一、继承和派生
1.是什么?
C++ 中的继承是类与类之间的关系,与现实世界中的继承类似
例如:儿子继承父亲的财产
继承(Inheritance)可以理解为一个类从另一个类获取成员变量和成员函数的过程
例如:
类B继承于类A,那么B就拥有A的成员变量和成员函数
在C++中,派生(Derive)和继承是一个概念,只是站的角度不同,
继承是儿子接收父亲的产业,派生是父亲把产业传承给儿子
被继承的类称为父类或基类,继承的类称为子类或派生类
“子类”和“父类”通常放在一起称呼,“基类”和“派生类”通常放在一起称呼
2.为什么?
子类除了拥有父类的成员,还可以定义自己的新成员,以增强类的功能
以达到青出于蓝胜于蓝,一代比一代强
以下是两种典型的使用继承的场景:
当你创建的新类与现有的类相似,只是多出若干成员变量或成员函数时,可以使用继承,这样不但会减少代码量,而且新类会拥有基类的所有功能
当你需要创建多个类,它们拥有很多相似的成员变量或成员函数时,也可以使用继承。可以将这些类的共同成员提取出来,定义为父类,然后从父类继承,既可以节省代码,也方便后续修改成员
下面我们定义一个父类 People,然后定义了子类Student
#include<iostream>
using namespace std;
//父类(基类) Pelple
class People {
private:
char *name;
int age;
public:
void setName(char *name) {
this->name = name;
}
char *getName() {
return this->name;
}
void setAge(int age) {
this->age = age;
}
int getAge() {
return this->age;
}
};
//父类(派生类) Student
class Student : public People {
private:
float score;
public:
void setScore(float score) {
this->score = score;
}
float getScore() {
return this->score;
}
};
//父类(派生类) Staff
class Staff : public People {
private:
float money;
public:
void setMoney(float money) {
this->money = money;
}
float getMoney() {
return this->money;
}
};
int main() {
// 创建Student学生对象
Student boy;
boy.setName("小明");
boy.setAge(16);
boy.setScore(95.5f);
cout << boy.getName() << "的年龄是 " << boy.getAge() << ",成绩是 " << boy.getScore() << endl;
// 创建Staff员工对象
Staff girl;
girl.setName("小丽");
girl.setAge(18);
girl.setMoney(15000.67);
cout << girl.getName() << "的年龄是 " << girl.getAge() << ",月工资是 " << girl.getMoney() << "\n";
return 0;
}
说明:
Student 类继承了 People 类的成员,同时还新增了自己的成员变量 score 和成员函数 setScore()、getScore()
继承过来的成员,可以通过子类对象访问,就像自己的一样
继承的一般语法为:
class 子类名:[继承方式]父类名{
子类新增加的成员
};
继承方式包括 public(公有的)、private(私有的)和 protected(受保护的),此项是可选的,如果不写,那么默认为 private
二、在子类的函数中调用父类的成员
1.为什么?
既然父类中定义了成员变量、成员函数,那么肯定就可以在子类的成员函数中进行使用,否则继承就没有意义了
2.使用 this 调用
在子类的函数中,调用从父类继承而来的成员变量或成员函数,直接使用 this
三、重写
子类定义了与父类相同名字的函数,覆盖了父类的这个函数
扩展或者重新编写功能
与重载不同,重载是函数名相同,但形参不同
注意:
被重写的父类成员函数,无论是否有重载,子类中都不会继承
除非使用了域解析运算符,才会调用父类的同名函数,子类中想要调用被覆盖的父类成员函数时,就需要使用作用域解析运算符 :: 来明确指定调用父类的版本,以避免产生歧义或错误。
四、多层继承
就是父类还有父类,父类的父类还有父类…
例如你爷爷有1000w,那么你爸爸就继承过来了,同样的道理 你也可以从你爸爸那里继承得到这笔钱
实例:
#include <iostream>
using namespace std;
class GrandPa {
public:
void display() {
cout << "GrandPa::display()\n";
}
void display_3() {
cout << "GrandPa::display_3()\n";
}
};
class Father : public GrandPa {
public:
void display() {
cout << "Father::display()\n";
}
void display_2() {
cout << "Father::display_2()\n";
}
};
class Children : public Father {
public:
void display() {
cout << "Children::display()" << "\n";
// 调用父类的成员函数
this->display_2();
// 调用被重写的父类成员函数
Father::display();
// 调用爷爷类中的成员函数
this->display_3();
// 调用被重写的爷爷类中的成员函数
GrandPa::display();
}
};
int main() {
Children boy;
boy.display();
return 0;
}
五、多继承
C++ 允许存在多继承,也就是一个子类可以同时继承多个父类
#include <iostream>
using namespace std;
class Father {
public:
void make_money() {
cout << "赚钱" << endl;
}
};
class Mother {
public:
void make_homework() {
cout << "做好菜" << endl;
}
};
class Son : public Father, public Mother {
};
int main() {
Son s;
s.make_money();
s.make_homework();
return 0;
}
当多个父类有相同的函数名
注意:要在子类中重写这个函数,否则会出现编译错误,原因是二义性