一文详解C#中重写(override)及覆盖(new)的区别
作者:letmebaby 发布时间:2021-07-17 02:36:32
1. 重写和覆盖的定义
1.1 重写(override)的定义
在C#中,用override关键字来重写一个父类中的虚方法或抽象方法。override关键字用于指示编译器,我要用派生类中的一个方法,重写基类中的同名方法。通过重写基类中的方法,可以实现多态性。有关重写与虚方法和抽象方法的详细示例,可移步C#虚方法和抽象方法示例。
override关键字的语法如下:
public override returnType MethodName(ParameterList)
{
// 方法实现
}
其中,public表示访问修饰符;override表示重写虚方法或抽象方法;returnType表示方法的返回类型;MethodName表示方法名称;ParameterList表示方法的参数列表。
需要注意的是,重写方法的访问修饰符必须与被重写方法的访问修饰符相同或更为宽松。
1.2 覆盖(new)的定义
在C#中,用new关键字来覆盖一个父类中的成员方法或成员变量。new关键字用于指示编译器,派生类中的一个方法或变量将隐藏基类中的同名方法或变量,从而改变了继承体系中的原有布局关系。
new关键字的语法如下:
new returnType MemberName(ParameterList)
{
// 成员实现
}
其中,returnType表示成员的返回类型;MemberName表示成员的名称;ParameterList表示成员的参数列表。
2. 两者的区别及示例
下面是一个示例:
//父类
public class FatherClass
{
public virtual string GetName()
{
return "我是父类中的虚拟方法";
}
}
//子类1
public class SonClass1 : FatherClass
{
public override string GetName()
{
return "我是子类1中的重写方法";
}
}
//子类2
public class SonClass2 : FatherClass
{
public new string GetName()
{
return "我是子类2中的覆盖方法";
}
}
随后通过程序入口函数调用:
public class Program
{
public static void Main(string[] args)
{
FatherClass fatherClass = new FatherClass();
Console.Write("直接调用父类中的虚方法:");
Console.WriteLine(fatherClass.GetName());
SonClass1 s1 = new SonClass1();
Console.Write("直接调用子类1中的重写方法:");
Console.WriteLine(s1.GetName());
SonClass2 s2 = new SonClass2();
Console.Write("直接调用子类2中的覆盖方法:");
Console.WriteLine(s2.GetName());
FatherClass f1 = new SonClass1();
Console.Write("声明父类,调用子类1中的重写方法:");
Console.WriteLine(f1.GetName());
FatherClass f2 = new SonClass2();
Console.Write("声明父类,调用子类2中的覆盖方法:");
Console.WriteLine(f2.GetName());
}
}
运行程序,得到的结果如下:
直接调用父类中的虚方法:我是父类中的虚拟方法
直接调用子类1中的重写方法:我是子类1中的重写方法
直接调用子类2中的覆盖方法:我是子类2中的覆盖方法
声明父类,调用子类1中的重写方法:我是子类1中的重写方法
声明父类,调用子类2中的覆盖方法:我是父类中的虚拟方法
总结:
1:不管是重写还是覆盖都不会影响父类自身的功能。
2:当用子类创建父类的时候,如 FatherClass f1 = new SonClass1(),重写会改变父类的功能,即调用子类的功能;而覆盖不会,仍然调用父类功能。
3:虚方法、实方法都可以被覆盖(new),但是抽象方法,接口 不可以。
4:抽象方法,接口,标记为virtual的方法可以被重写(override),实方法不可以。
5:重写使用的频率比较高,实现多态;覆盖用的频率比较低,用于对以前无法修改的类进行继承的时候。
小拓展:当使用new关键字覆盖一个成员方法或变量时,隐藏的成员在类层次结构中的位置会改变,它会在派生类中被重新定义,而不是从基类中继承。当基类对象引用派生类对象时,派生类中隐藏的成员不被基类引用所包含,因此它们无法访问。而在派生类中,新定义的成员将起作用,完全与基类中的同名成员无关。
来源:https://www.cnblogs.com/letmebaby/p/17261435.html


猜你喜欢
- 在定义一个Rest接口时通常会利用GET、POST、PUT、DELETE来实现数据的增删改查;这几种方式有的需要传递参数,后台开发人员必须对
- 一、Spring Boot Admin 的概念 Spring Boot Admin是一个
- 本文实例讲述了C#使用iTextSharp设置PDF所有页面背景图功能的方法。分享给大家供大家参考。具体如下:在生成PDF 的时候,虽然可以
- jar与warSpring Boot项目开发完成后,需要以jar或war的方式将项目打包部署到测试开发环境。jar即Java Archive
- 目录1、下面的代码运行的结果是:2、下面有关java实例变量,局部变量,类变量和final变量的说法,错误的是?3、执行如下代码段后,变量s
- 这次记录的是实现Android图片两手触控缩放的功能。编译环境:eclipseAndroid版本4.0创建工程过程略实现图片在页面两手触控缩
- 一、Spring Boot任务线程池线程池的作用防止资源占用无限的扩张调用过程省去资源的创建和销毁所占用的时间在高并发环境下,不断的分配新资
- 前台处理首先前台先要获取所有的要删除数据的ID,并将ID拼接成字符串 例如: 2,3,4,5,然后通过GET请求返送到后台。后台处理控制器接
- 一、new 对象的几种说法初学 Java 面向对象的时候,实例化对象的说法有很多种,我老是被这些说法给弄晕。public class Tes
- 前言作为一个服务端开发感觉一直挺排斥框架这种东西的,总觉得什么实现逻辑都帮你封装在里面了,你只需要配置这配置那个,出了问题也不知道怎么排查,
- //有何不足或者问题希望能够得到各位的多多指正,不胜感激import java.util.Scanner;/** *
- 构造方法以及参数:PageView可用于Widget的整屏滑动切换,如当代常用的短视频APP中的上下滑动切换的功能,也可用于横向页面的切换,
- 编程是一门艺术,大批量的改动显然是非常丑陋的做法,用心的琢磨写的代码让它变的更美观。在有些情况下,一个客户不能或者不想直接访问另一个对象,这
- Task的应用Task的MSDN的描述如下:【Task类的表示单个操作不会返回一个值,通常以异步方式执行。Task对象是一种的中心思想基于任
- 第一次是接触Lambda表达式是在TypeScript中(JavaScript的超集中),当时是为了让TypeScript的this方法外而
- 1. 判断允许上传文件的 文件后缀/图片后缀/相片后缀 和 其它工具类import org.springframework.stereoty
- 话不多说,请看代码:<!DOCTYPE html><html><head> <meta
- 今天没有继续学习新知识点,画出了一个随鼠标画出的 图形,知识点全都是之前学的,话不多说,先上图:代码部分: // ope
- 目录前言应用定义基本Enum特性Enum的静态导入Enum中添加新方法Switch语句中的EnumEnum的继承EnumSet的使用Enum
- 前言在之前的项目中,有做过一个需求,需要实现一个颜色渐变的折线图。当时项目中使用的图表库是MPAndroidChart,但是该库没有提供合适