文章目录
- 继承
- 1. 继承
- 1.1 什么是继承
- 1.2 C++ 继承方式
- 1.2.1 基本案例
- 1.2.2 继承权限组合
- 1.2.3 继承中构造函数的说法
- 1.2.4 继承中析构函数的执行顺序
- 1.2.5 继承中变量名称冲突问题
- 1.2.6 继承中函数【重写】
继承
1. 继承
1.1 什么是继承
面向对象程序设计中最重要的一个概念是继承。继承允许我们依据另一个类来定义一个类,这使得创建和维护一个应用程序变得容易。达到重写代码功能和提高执行效率的效果。
当创建一个类时,不需要重新编写新的数据成员和成员函数, 只需要指定新键的类继承了一个已有的类的成员即可。这个已有的类称为基类,新建的类称为派生类。
1.2 C++ 继承方式
1.2.1 基本案例
格式
class 子类 : 权限修饰符
{
}
#include <iostream>
using namespace std;
class Base
{
public:
int mA = 1;
protected:
int mB = 2;
private:
int mC = 3;
};
/*
Base 类是 Son 的一个 public 修饰父类
Son 类是 Base 类的一个子类,或者可以认为 Son 类是 Base 类 派生类
*/
class Son : public Base
{
public:
int nA = 1;
protected:
int nB = 2;
private:
int nC = 3;
};
int main(int argc, char const *argv[])
{
Son * s = new Son;
cout << "mA : " << s->mA << endl;
// 当情况下,mB 是 Base 类中的 protected 修饰 成员变量,同时使用 public 方式继承
// 子类对象无法在类外调用 mB
// cout << "mB : " << s->mB << endl;
// 当情况下,mB 是 Base 类中的 protected 修饰 成员变量,同时使用 public 方式继承
// 子类对象无法s使用mC
// cout << "mC : " << s->mC << endl;
cout << "nA : " << s->nA << endl;
// cout << "nB : " << s->nB << endl;
// cout << "nC : " << s->nC << endl;
return 0;
}
1.2.2 继承权限组合
继承对应的权限修饰\原修饰符 | public | protected | private |
---|---|---|---|
public | public | protected | 无法继承 |
protected | protected | protected | 无法继承 |
private | private | private | 无法继承 |
#include <iostream>
using namespace std;
/*
public:
类内、子类类外都可以使用
protected:
类内、子类可以使用,类外无法使用
private:
类内可以使用,子类、类外无法使用
*/
class Base
{
public:
int mA = 1;
void test1() { cout << "test1 funtion" << endl; }
protected:
int mB = 1;
void test2() { cout << "test2 funtion" << endl; }
private:
int mC = 1;
void test3() { cout << "test3 funtion" << endl; }
};
/*
public 继承方式,父类的成员权限修饰符变化
public --> public
protected --> protected
private 无法继承
*/
class Son1: public Base
{
public:
void test()
{
cout << mA << endl;
cout << mB << endl;
// cout << mC << endl;
test1();
test2();
// test3();
}
};
/*
protected 继承方式,父类的成员权限修饰符变化
public --> protected
protected --> protected
private 无法继承
*/
class Son2: protected Base
{
public:
void test()
{
cout << mA << endl;
cout << mB << endl;
// cout << mC << endl;
test1();
test2();
// test3();
}
};
/*
private 继承方式,父类的成员权限修饰符变化
public --> private
protected --> private
private 无法继承
*/
class Son3: private Base
{
void test()
{
cout << mA << endl;
cout << mB << endl;
// cout << mC << endl;
}
};
int main(int argc, char const *argv[])
{
Son1 *s1 = new Son1;
cout << s1->mA << endl;
Son2 *s2 = new Son2;
// cout << s2->mA << endl;
Son3 *s3 = new Son3;
// cout << s3->mA << endl;
return 0;
}
1.2.3 继承中构造函数的说法
#include <iostream>
using namespace std;
class Base
{
public:
Base()
{
cout << "Base 类中的构造函数" << endl;
}
~Base()
{
cout << "Base 类析构函数" << endl;
}
};
class Son : public Base
{
public:
Son()
{
cout << "Son 类构造函数" << endl;
}
~Son()
{
cout << "Son 类析构函数" << endl;
}
};
class GrandSon : public Son
{
public:
GrandSon()
{
cout << "GrandSon 类析构函数" << endl;
}
~GrandSon()
{
cout << "GrandSon 类析构函数" << endl;
}
};
int main(int argc, char const *argv[])
{
// 显式调用的时子类的五承诺书构造函数
Son *s1 = new Son();
/*
Base 类构造函数
Son 类构造函数
*/
cout << "----------------------------------" << endl;
delete s1;
/*
Son 类析构函数
Base 类析构函数
*/
cout << "----------------------------------" << endl;
GrandSon *s2 = new GrandSon();
/*
Base 类构造函数
Son 类构造函数
GrandSon 类构造函数
*/
cout << "----------------------------------" << endl;
delete s2;
/*
GranSon 类析构函数
Son 类析构函数
Base 类析构函数
*/
return 0;
}
1.2.4 继承中析构函数的执行顺序
1.2.5 继承中变量名称冲突问题
class Base
{
public:
int num;
};
class Son : public Base
{
public:
int num;
void test()
{
// int Son::num;
/*
如果直接使用,编译器会考虑按照就近原则方式进行数据分配
首选是 Son 类中的 num 数据
*/
cout << num << endl;
// int Base::num;
/*
如果需要使用 Base 中的 num,需要利用 :: 作用域运算符
限制当前变量的作用范围
*/
cout << Base::num << endl;
}
};
1.2.6 继承中函数【重写】
#include <iostream>
using namespace std;
class Father
{
public:
void name() { cout << "小鱼丸" << endl; }
void hobby() { cout << "唱歌" << endl; }
};
/*
函数的重写 Ovreride
1. 存在必要的继承关系
2. 要求子类重写父类的函数,函数声明必须一致
3. 可以按照子类要求完成哈桑农户内容实现
重写的存在可以降低开发中函数命名压力
*/
class Son : public Father
{
public:
void name() { cout << "Glade" << endl; }
void hobby() { cout << "吃" << endl; }
};
int main(int argc, char const *argv[])
{
Son * s = new Son;
/*
子类可以通过 public 继承得到父类中 public 修饰函数,
类内调用但是父类的函数有可能无法满足子类的特征需求
【重写父类函数】 Override
*/
s->name();
s->hobby();
return 0;
}
{
public:
void name() { cout << "Glade" << endl; }
void hobby() { cout << "吃" << endl; }
};
int main(int argc, char const *argv[])
{
Son * s = new Son;
/*
子类可以通过 public 继承得到父类中 public 修饰函数,
类内调用但是父类的函数有可能无法满足子类的特征需求
【重写父类函数】 Override
*/
s->name();
s->hobby();
return 0;
}