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

C++ 覆盖方法与重载方法

覆盖方法(overriding)

什么是类函数的覆盖方法:
覆盖方法用于同一函数的重写派生类函数覆盖基类同名函数
覆盖方法重写(覆盖)了一个方法,以实现不同的功能.一般是用于子类在继承父类时,重写(重新实现)父类中的方法

覆盖方法的特征:

范围不同(分别位于 基类 和 派生类中)
函数名字相同
函数参数相同
基类函数必须有virtual(虚函数)关键字

为什么需要覆盖方法:
在 C++ 里,当我们需要在 基类里提供一个通用的函数,但是在它的某个子类里,需要修改这个方法(通用函数)的实现,就要用到覆盖方法
当父类中的某些方法不能满足要求时,子类中改写父类的方法

注意:
1.重写方法的 参数列表(方法名称,参数列表,返回类型)必须完全与被重写的方法相同否则不能称其为覆盖而是 重载
2.重写方法的 访问修饰符一定要大于被重写方法的访问修饰符(public>protected>default>private)
3.重写的方法的返回值必须和被重写的方法的返回一致
3.被重写的方法不能为private,否则在其子类中只是新定义了一个方法,并没有对其进行重写
5.静态方法不能被重写为非静态的方法(会编译出错)


覆盖方法例程

#include <iostream>
#include <string>

using namespace std;

//todo覆盖方法

class Animal
{
public:
		Animal(string name);
		void eat();//基类中的eat()方法 因为monkey和turtle都具有eat的功能 所有选择此方法为被覆盖重写的通用方法
		void sleep();
		void run();
protected:
		string thename;
};

class Monkey :public Animal//todo建立一个继承自Animal基类的子类Monkey
{
	public:
		Monkey(string name);
		void climb();
		
		void eat();//todo再一次声明基类中的通用函数eat() 
		//注意: 重写方法的参数列表必须完全与被重写的方法相同 否则不能称其为 覆盖 而是 重载
		//			重写方法的访问修饰符一定要大于被重写方法的访问修饰符(public>protected>default>private)
		//			重写的方法的返回值必须和被重写的方法的返回一致
		//			被重写的方法不能为private,否则在其子类中只是新定义了一个方法,并没有对其进行重写
		//			静态方法不能被重写为非静态的方法(会编译出错)

};


class Turtle :public Animal
{
public:
	Turtle(string name);
	void swim();
	void eat();
};


//todo基类Animal的构造器定义与成员函数定义
Animal::Animal(string name)
{	
	thename = name;
}

void Animal::eat()//todo基类中的通用方法eat的定义
{
	cout << "基类中状态 :吃东西" << endl;
}

void Animal::sleep()
{
	cout << "基类中状态 :睡觉" << endl;
}

void Animal::run()
{
	cout << "基类中状态 :跑动" << endl;
}

//todo子类Monkey的构造器定义与成员函数定义
Monkey::Monkey(string name) :Animal(name)
{
}

void Monkey::climb()
{
	cout << "子类中monkey状态 :爬树" << endl;
}

void Monkey::eat()//todo继承基类Animal后的子类Monkey的 通用函数eat通用方法的覆盖
{
	Animal::eat();
	cout << "覆盖后monkey的eat状态 :'我在吃香蕉' " << endl;
}



//todo子类Turtle的构造器定义与成员函数定义
Turtle::Turtle(string name) :Animal(name)
{
}

void Turtle::swim()
{
	cout << "子类中Turtle状态 :游泳" << endl;
}

void Turtle::eat()
{
	Animal::eat();
	cout << "覆盖后turtle的eat状态 :'我在吃水草' " << endl;
}

int main()
{	
	Monkey monkey("小猪猪");
	Turtle turtle("小甲鱼");

	//todo调用覆盖方法
	monkey.eat();
	turtle.eat();

	monkey.climb();
	turtle.swim();

	return 0;
}

结果
在这里插入图片描述


重载方法(overload)

什么是类函数的重载方法:

对于类的方法(包括从父类中继承的方法), 方法名相同,参数列表不同的方法之间就构成了重载关系 ,这里有两个问题需要注意

1.参数列表又叫参数签名,指三样东西: 参数的类型,参数的个数,参数的顺序 ,这三者只要有一个不同就叫做参数列表不同

2.重载关系只能发生在同一个类中吗?非也,这时候你要深刻理解继承,要知道一个子类所拥有的成员除了自己显式写出来的以外,还有父类遗传下来的,所以子类中的某个方法和父类中继承下来的方法也可以发生重载的关系

为什么需要重载方法:

类重载机制使你可以定义多个同名的方法(函数),只是他们的输入参数必须不同(编译器是依靠不同的输入参数来区分不同的方法)

注意:🎯

对从基类继承来的方法进行重载,程序将永远编译不过(子类中不可重载继承自基类的方法) 因为如果在子类中进行基类中某方法的重新定义,就变成了覆盖方法 (进行覆盖前提是覆盖函数和被覆盖函数的函数名和参数列表一致)


重载方法例程

class Animal
{
public:
	Animal(string name);
	void eat();
	void eat(string food);//todo基类中进行eat函数的重载
	void eat(int count);//todo再次进行eat函数的重载
	void sleep();
	void run();

protected:
	string thename;
};

class Monkey :public Animal
{
public:
	Monkey(string name);
	void climb();
	//void eat(float a);
	//todo如果在子类中进行基类中某方法的重新定义 就变成了覆盖方法  在具体定义此方法时 程序将会报错
};


class Turtle :public Animal
{
public:
	Turtle(string name);
	void swim();
};


//todo基类Animal的构造器定义与成员函数定义
Animal::Animal(string name)
{
	thename = name;
}

void Animal::eat()
{
	cout << "基类中状态 :吃东西" << endl;
}

void Animal::eat(string food)//todo基类中的函数eat进行重载
{
	cout << "我吃的是"<<food << endl;
}

void Animal::eat(int count)//todo基类中的函数eat再次进行重载
{
	cout << "我吃了" <<count<<"根"<< endl;
}


void Animal::sleep()
{
	cout << "基类中状态 :睡觉" << endl;
}

void Animal::run()
{
	cout << "基类中状态 :跑动" << endl;
}


//todo子类Monkey的构造器定义与成员函数定义
Monkey::Monkey(string name) :Animal(name)
{
}

void Monkey::eat(float a)
{
		
}

void Monkey::climb()
{
	cout << "子类中monkey状态 :爬树" << endl;
}

//todo子类Turtle的构造器定义与成员函数定义
Turtle::Turtle(string name) :Animal(name)
{
}

void Turtle::swim()
{
	cout << "子类中Turtle状态 :游泳" << endl;
}



int main()
{
	Monkey monkey("小猪猪");
	Turtle turtle("小甲鱼");

	monkey.eat();
	turtle.eat();

	monkey.eat("香蕉");//调用重载函数一
	monkey.eat(15);//调用重载函数二

	return 0;
}

//https://www.jianshu.com/p/00b4fa11d63e

结果
在这里插入图片描述


总结:🎯

类函数的覆盖和重载具有以下相同点:
1.都要求类函数同名
2.都可以用于抽象类函数和非抽象类函数之间

类函数的覆盖和重载在使用时有以下区别:
1.覆盖 要求类函数的参数列表(参数签名)必须一致 重载 要求参数必须不一致
2.覆盖 要求返回类型必须一致 重载 没有要求
3.覆盖 只能用于子类覆盖基类的类函数 重载 同一个类的所有方法都会被重载 (包括从父类中继承而来的方法)但不可在子类中重载父类中的方法
4.覆盖 对方法的访问权限和抛出的异常有特殊要求 重载 没有限制
5.覆盖 父类中的一个方法只能被子类覆盖一次 重载 一个方法可以在所有类中被重载多次

相关文章:

  • Ubuntu 12.04 ping 响应慢
  • C++ 静态属性和静态方法
  • C++ this指针与静态属性的关系
  • .NET I/O 学习笔记:对文件和目录进行解压缩操作
  • C++ new和delete动态分配和释放内存
  • C++ 类对象与类指针(静态和动态多态)
  • 第六天 if if…else 三木运算符
  • C++ 虚函数与多态性
  • pb11.2build8949 数据窗口dw limit有关问题
  • VS 监视功能
  • C++ 抽象类
  • C++ 运算符重载
  • 购买Microsoft Technet订阅,免费获得微软几乎所有的产品序列号“用于评估”,...
  • C++ 操作符重载
  • 客户端调用webservice的两种方式
  • angular2开源库收集
  • css选择器
  • JSDuck 与 AngularJS 融合技巧
  • js操作时间(持续更新)
  • JS函数式编程 数组部分风格 ES6版
  • JS学习笔记——闭包
  • Netty源码解析1-Buffer
  • PAT A1017 优先队列
  • springMvc学习笔记(2)
  • TypeScript迭代器
  • Vim 折腾记
  • vuex 学习笔记 01
  • 第2章 网络文档
  • 第三十一到第三十三天:我是精明的小卖家(一)
  • 爬虫进阶 -- 神级程序员:让你的爬虫就像人类的用户行为!
  • 悄悄地说一个bug
  • 限制Java线程池运行线程以及等待线程数量的策略
  • 学习笔记:对象,原型和继承(1)
  • C# - 为值类型重定义相等性
  • ​MPV,汽车产品里一个特殊品类的进化过程
  • ​香农与信息论三大定律
  • ​业务双活的数据切换思路设计(下)
  • # 再次尝试 连接失败_无线WiFi无法连接到网络怎么办【解决方法】
  • #我与Java虚拟机的故事#连载19:等我技术变强了,我会去看你的 ​
  • (1)(1.8) MSP(MultiWii 串行协议)(4.1 版)
  • (33)STM32——485实验笔记
  • (C++)八皇后问题
  • (C语言)fgets与fputs函数详解
  • (附源码)springboot“微印象”在线打印预约系统 毕业设计 061642
  • (五)网络优化与超参数选择--九五小庞
  • (一)基于IDEA的JAVA基础1
  • (转)c++ std::pair 与 std::make
  • (转)jdk与jre的区别
  • .net core 3.0 linux,.NET Core 3.0 的新增功能
  • .net 发送邮件
  • .Net 中的反射(动态创建类型实例) - Part.4(转自http://www.tracefact.net/CLR-and-Framework/Reflection-Part4.aspx)...
  • .NET4.0并行计算技术基础(1)
  • .net6+aspose.words导出word并转pdf
  • .net快速开发框架源码分享
  • @AutoConfigurationPackage的使用