1.派生语法
语法如下:
class Base{
};
class Name:access-specifier Base{
//access-specifier可以是public、private、protect
};
一个简单的继承结构程序:
#include <iostream>
using namespace std;
// 定义一个基类Fish
class Fish {
public:
bool isFreshWaterFish; // 一个布尔型成员变量,表示鱼是淡水鱼还是咸水鱼
// 一个虚函数Swim,根据鱼的种类输出不同的游泳场所
void Swim() {
if (isFreshWaterFish) {
cout << "swim in lake" << endl; // 如果是淡水鱼,输出在湖中游泳
} else {
cout << "swim in sea" << endl; // 如果是咸水鱼,输出在海中游泳
}
}
};
// 定义一个派生类Tuna,继承自Fish
class Tuna : public Fish {
public:
Tuna() {
isFreshWaterFish = false; // 将isFreshWaterFish设置为false,表示Tuna是咸水鱼
}
};
// 定义另一个派生类Carp,同样继承自Fish
class Carp : public Fish {
public:
Carp() {
isFreshWaterFish = true; // 将isFreshWaterFish设置为true,表示Carp是淡水鱼
}
};
int main() {
Carp lunch; // 创建一个Carp类型的对象lunch
Tuna dinner; // 创建一个Tuna类型的对象dinner
cout << "lunch: " << endl; // 输出午餐的描述
lunch.Swim(); // 调用lunch的Swim函数
cout << "dinner: " << endl; // 输出晚餐的描述
dinner.Swim(); // 调用dinner的Swim函数
system("pause");
return 0;
}
2.访问限定符protected
将属性声明为protected时,允许友元类和派生类访问该属性,但禁止在继承结构之外访问
示例代码如下
class Fish
{
protected://声明为protected
bool isFreshWaterFish;
public:
void Swim(){
if (isFreshWaterFish)
{
cout<<"swim in lake"<<endl;
}
else{
cout<<"swim in sea"<<endl;
}
}
};
3.基类初始化
如果基类包含重载的构造函数,可以使用初始化列表传递参数
示例代码如下:
#include <iostream>
using namespace std;
// 定义基类Fish
class Fish {
protected:
bool isFreshWaterFish; // 一个受保护的布尔型成员变量,表示鱼是淡水鱼还是咸水鱼
Fish(bool isFreshWater) : isFreshWaterFish(isFreshWater) {}
// 构造函数,根据传入的参数初始化isFreshWaterFish
public:
// 一个虚函数Swim,根据鱼的种类输出不同的游泳场所
void Swim() {
if (isFreshWaterFish) {
cout << "swim in lake" << endl; // 如果是淡水鱼,输出在湖中游泳
} else {
cout << "swim in sea" << endl; // 如果是咸水鱼,输出在海中游泳
}
}
};
// 定义派生类Tuna,继承自Fish
class Tuna : public Fish {
public:
// Tuna的构造函数,使用Fish的构造函数并传入false,表示Tuna是咸水鱼
Tuna() : Fish(false) {}
};
// 定义另一个派生类Carp,同样继承自Fish
class Carp : public Fish {
public:
// Carp的构造函数,使用Fish的构造函数并传入true,表示Carp是淡水鱼
Carp() : Fish(true) {}
};
int main() {
Carp lunch; // 创建一个Carp类型的对象lunch
Tuna dinner; // 创建一个Tuna类型的对象dinner
cout << "lunch: " << endl; // 输出午餐的描述
lunch.Swim(); // 调用lunch的Swim函数
cout << "dinner: " << endl; // 输出晚餐的描述
dinner.Swim(); // 调用dinner的Swim函数
system("pause");
return 0;
}
这样可以强迫在构造一个派生类时,必须定义一个这样的函数来为其赋值,避免不定义的情况下,随机数值产生影响
4.在派生类中覆盖基类方法
只要派生类中实现了从基类中继承的函数,且返回值和标值相同,就可以覆盖
class Fish
{
protected:
bool isFreshWaterFish;
Fish(bool isFreshWater):isFreshWaterFish(isFreshWater){};
public:
void Swim(){
if (isFreshWaterFish)
{
cout<<"swim in lake"<<endl;
}
else{
cout<<"swim in sea"<<endl;
}
}
};
class Tuna:public Fish{
public:
Tuna():Fish(false){};
void Swim(){//覆盖基类中的方法
cout<<"fu gai"<<endl;
}
};
5.调用基类中已经被覆盖的方法
使用作用域解析运算符::
Dinner.Fish::Swim();//调用基类中的方法
Dinner.Swim();//调用覆盖后的方法
6.在派生类中的覆盖方法中,调用基类方法
同样使用作用域解析运算符::
class Fish
{
protected:
bool isFreshWaterFish;
Fish(bool isFreshWater):isFreshWaterFish(isFreshWater){};
public:
void Swim(){
if (isFreshWaterFish)
{
cout<<"swim in lake"<<endl;
}
else{
cout<<"swim in sea"<<endl;
}
}
};
class Tuna:public Fish{
public:
Tuna():Fish(false){};
void Swim(){//覆盖基类中的方法
cout<<"fu gai"<<endl;
Fsih::Swim();//调用基类方法
}
};
7.派生类中隐藏的基类方法
覆盖是一种极端情况,即派生类中的重载方法会隐藏基类中方法的所有重载版本,导致需要调用时无法调用,示例代码如下
#include <iostream>
using namespace std;
// 定义基类Fish
class Fish {
public:
// 定义一个成员函数Swim
void Swim() {
cout << "Fish swim" << endl;
}
// 重载Swim函数,带有一个布尔参数isFreshWaterFish
void Swim(bool isFreshWaterFish) {
if (isFreshWaterFish) {
cout << "swim in lake" << endl;
} else {
cout << "swim in sea" << endl;
}
}
};
// 定义派生类Tuna,
class Tuna : public Fish {
public:
// 重写基类Fish的Swim成员函数
void Swim() {
cout << "fu gai" << endl;
}
};
int main() {
Tuna dinner; // 创建Tuna类的对象dinner
cout << "dinner: " << endl;
dinner.Swim(); // 调用dinner对象的Swim函数,由于Tuna类重写了Swim,所以调用的是Tuna类的Swim
dinner.Swim(false); //ERROR,因为派生类中的重载函数Swim(bool isFreshWaterFish)已经被覆盖了
system("pause");
return 0;
若想调用基类中的方法
解决办法1: 使用作用域解析符::
dinner.Fish::Swim(false);
解决方法2: 在派生类中使用using
解除隐藏
#include <iostream>
using namespace std;
class Fish
{
public:
void Swim(){
cout<<"Fish swim"<<endl;
}
void Swim(bool isFreshWaterFish){
if (isFreshWaterFish)
{
cout<<"swim in lake"<<endl;
}
else{
cout<<"swim in sea"<<endl;
}
}
};
class Tuna:public Fish{
public:
using Fish::Swim;//解除隐藏
void Swim(){
cout<<"fu gai"<<endl;
}
};
int main(){
Tuna dinner;
cout<<"dinner: "<<endl;
dinner.Swim();
dinner.Swim(false);//可以正常调用了
system("pause");
return 0;
}
解决方法3: 在派生类中,把基类中的方法全部重载一次,且在重载方法中就调用基类方法
#include <iostream>
using namespace std;
class Fish
{
public:
void Swim(){
cout<<"Fish swim"<<endl;
}
void Swim(bool isFreshWaterFish){
if (isFreshWaterFish)
{
cout<<"swim in lake"<<endl;
}
else{
cout<<"swim in sea"<<endl;
}
}
};
class Tuna:public Fish{
public:
//重载基类中的方法Swim()
void Swim(){
cout<<"fu gai"<<endl;
}
//重载基类中的重载方法Swim(bool isFreshWaterFish)
void Swim(bool isFreshWaterFish){
Fish::Swim(isFreshWaterFish);//直接调用基类中的方法
}
};
int main(){
Tuna dinner;
cout<<"dinner: "<<endl;
dinner.Swim();
dinner.Swim(false);//可以正常运行了
system("pause");
return 0;
}