C++ 教程 - 06 类的封装、继承、多态

文章目录

封装

  • 在private/protected 模块放置数据或者底层算法实现;
  • 在public块提供对外接口,实现相应的功能调用;
  • 类的封装案例
#include <iostream>
using namespace std;


// 类的定义 一般放在头文件
class Stu {

public: // 公有权限 接口

	void setAge(const int& age) {
		this->age = age;
	}

	const int& getAge() const {
		return age;
	}

private: // 数据封装
	int age;
};

int main() {
	// 创建对象
	Stu s1; 
	s1.setAge(20);
	cout << s1.getAge() << endl;
	return 0;
}

继承

  • 将一个类的成员变量、成员函数,应用到另一个类中,实现复用;
  • 支持多继承,同python一样;而 java 仅支持单继承;
  • 继承修饰符public、protected、private; 若不写修饰符,则默认private继承;
  • public继承,基类中的public、protected、private 保持不变;
  • protected继承,基类中的public、protected、private 变为protected、protected、private
  • private继承, 基类中的public、protected、private全部变为private;
  • 子类继承父类的所有函数,除了:
    • 构造函数、拷贝构造函数;
    • 析构函数;
    • 友元函数、重载运算符
#include <iostream>
#include <string>
using namespace std;


// 基类
class People {
public:
	string name;
	People(const string& name, const int& age, const double& height) {
		this->name = name;
		this->age = age;
		this->height = height;
		cout << "父类完成初始化" << height << endl;
	}
	void printName() const {
		cout << "name:" << name << endl;
	}

	void printAge() const {
		cout << "age:" << this->age << endl;
	}

	void printHeight() const {
		cout << "height:" << this->height << endl;
	}

protected:
	int age;

private:
	double height;
};

// 类的定义 一般放在头文件
class Stu: public People { // 公有继承(经常使用)
public: // 可多个块
	int num; // 若未放在public等修饰符下, 默认私有
	Stu(const string& name, const int& age, const double&heigh): People(name, age, heigh){// 显式调用父类的有参构造,否则隐式调用父类的无参构造;
		// 子类的构造 初始化
		this->num = 102;
	}

	void printAge() const {// 子类方法中,只能访问继承的public/protected 成员,private成员无法访问,但可以通过父类的方法到父类代码中访问;
		cout << "age:" << this->age << endl;
	}
	/*void printHeight() const {
		cout << "height:" << this->height << endl;
	}  不可访问继承的私有 */

};


int main() {

	string name = "jack";
	int age = 20;
	double height = 23.5;
	// 创建对象
	Stu s1(name, age, height);  // 父类的构造方法 完成对私有变量的初始化
	s1.printName();
	s1.printAge();
	s1.printHeight(); // 在父类中访问私有	
	return 0;
}

在这里插入图片描述

多态

  • 多个子类继承父类中的方法,可以分别实现方法的重写(改函数体);
  • 父类中常采用 virtual 声明为虚函数,然后子类继承并重写;
  • virtual 函数体赋值为=0,则为纯虚函数,所有的纯虚函数必须重写;
  • 含有纯虚函数的类是抽象类,无法直接实例化,必须被继承;
    在这里插入图片描述

子类重写普通的成员函数

#include <iostream>
#include <string>
using namespace std;

// 基类
class People {
public:
	void printCate() {
		cout << "class People" << endl;
	}
};


//
class Stu: public People { // 公有继承
public:
	void printCate() { // 重写父类的 普通成员函数
		cout << "class Stu" << endl;
	}
	void run(){
		cout << "stu run." << endl; // 子类自定义函数
	}
};


class Teacher : public People { // 公有继承
public:
	void printCate() { // 重写父类的 普通成员函数
		cout << "class Teacher" << endl;
	}
};


class Worker : public People { // 公有继承
public:
	void printCate() { // 重写父类的 普通成员函数
		cout << "class Worker" << endl;
	}
};


int main() {

	People* ptr; // 向上造型:父类型指针 指向子类的对象(java中可以用父类声明变量,并赋值子类对象)
	Stu stu;
	Teacher tea;
	Worker wk;
	
	ptr = &stu; // 父类型的指针指向 子类Stu的对象
	ptr->printCate(); //  指针调用子类对象的任何public成员,均走父类(除非重写虚函数)
	ptr->run(); // 无法调用Stu子类中的成员
	
	ptr = &tea;
	ptr->printCate();

	ptr = &wk;
	ptr->printCate();
	return 0;
}

输出:
在这里插入图片描述
把父类的普通成员函数加virtual关键字修饰,子类再次继承重写,向上造型指针调用子类对象的函数就可以走子类重写的虚函数;如下加virtual关键字:


// 基类
class People {
public:
	virtual void printCate() {
		cout << "class People" << endl;
	}
};


//
class Stu: public People { // 公有继承
public:
	virtual void printCate() { // 重写父类的 虚成员函数
		cout << "class Stu" << endl;
	}
};


class Teacher : public People { // 公有继承
public:
	virtual void printCate() { // 重写父类的 普通成员函数
		cout << "class Teacher" << endl;
	}
};


class Worker : public People { // 公有继承
public:
	virtual void printCate() { // 重写父类的 普通成员函数
		cout << "class Worker" << endl;
	}
};

 
抽象基类中的所有的纯虚函数,必须重写:

#include <iostream>
#include <string>
using namespace std;


// 抽象基类(接口),无法直接实例化
class People {
public:
	string name;
	virtual void printCate() = 0; // 纯虚函数,没有函数体
	virtual void setName(const string& name) = 0;
	virtual const string& getName() = 0;
};


//
class Stu: public People { // 公有继承
public:
	virtual void printCate() {
		// 必须重写  抽象基类的  所有的纯虚函数;
		cout << "Stu 实现printCate接口" << endl;
	}
	virtual void setName(const string& name) { // 必须重写  抽象基类的  所有的纯虚函数;
		this->name = name;
	}
	virtual const string& getName() { // 必须重写  抽象基类的  所有的纯虚函数;
		return this->name;
	}
};



int main() {

	Stu s;
	s.setName("jack");
	cout << s.getName() << endl;
	
	return 0;
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

laufing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值