c# override用法
要扩展或修改继承的方法、属性、索引器或事件的抽象实现或虚实现,必须使用 override 修饰符。
在此例中,类 Square 必须提供 Area 的重写实现,因为 Area 是从抽象的 ShapesClass 继承而来的。
abstract class ShapesClass
{
abstract public int Area();
}
class Square : ShapesClass
{
int x, y;
// Because ShapesClass.Area is abstract, failing to override
// the Area method would result in a compilation error.
public override int Area()
{
return x * y;
}
}
有关 override 关键字用法的更多信息,请参见使用 Override 和 New 关键字进行版本控制以及了解何时使用 Override 和 New 关键字。
备注override 方法提供从基类继承的成员的新实现。通过 override 声明重写的方法称为重写基方法。重写的基方法必须与 override 方法具有相同的签名。有关继承的信息,请参见继承。
不能重写非虚方法或静态方法。重写的基方法必须是 virtual、abstract 或 override 的。
override 声明不能更改 virtual 方法的可访问性。override 方法和 virtual 方法必须具有相同的访问级别修饰符。
不能使用修饰符 new、static、virtual 或 abstract 来修改 override 方法。
重写属性声明必须指定与继承属性完全相同的访问修饰符、类型和名称,并且被重写的属性必须是 virtual、abstract 或 override 的。
示例此示例定义了一个名为 Employee 的基类,和一个名为 SalesEmployee 的派生类。SalesEmployee 类包括一个额外的属性 salesbonus,并重写方法 CalculatePay 以便将该属性考虑在内。
using System;
class TestOverride
{
public class Employee
{
public string name;
// Basepay is defined as protected, so that it may be
// accessed only by this class and derrived classes.
protected decimal basepay;
// Constructor to set the name and basepay values.
public Employee(string name, decimal basepay)
{
this.name = name;
this.basepay = basepay;
}
// Declared virtual so it can be overridden.
public virtual decimal CalculatePay()
{
return basepay;
}
}
// Derive a new class from Employee.
public class SalesEmployee : Employee
{
// New field that will affect the base pay.
private decimal salesbonus;
// The constructor calls the base-class version, and
// initializes the salesbonus field.
public SalesEmployee(string name, decimal basepay,
decimal salesbonus) : base(name, basepay)
{
this.salesbonus = salesbonus;
}
// Override the CalculatePay method
// to take bonus into account.
public override decimal CalculatePay()
{
return basepay + salesbonus;
}
}
static void Main()
{
// Create some new employees.
SalesEmployee employee1 = new SalesEmployee("Alice",
1000, 500);
Employee employee2 = new Employee("Bob", 1200);
Console.WriteLine("Employee " + employee1.name +
" earned: " + employee1.CalculatePay());
Console.WriteLine("Employee " + employee2.name +
" earned: " + employee2.CalculatePay());
}
}
输出
Employee Alice earned: 1500
Employee Bob earned: 1200
使用 Override 和 New 关键字进行版本控制(C# 编程指南) C# 语言经过专门设计,以便不同库中的基类与派生类之间的版本控制可以不断向前发展,同时保持向后兼容。这具有多方面的意义。例如,这意味着在基类中引入与派生类中的某个成员具有相同名称的新成员在 C# 中是完全支持的,不会导致意外行为。它还意味着类必须显式声明某方法是要重写一个继承方法,还是一个仅隐藏具有类似名称的继承方法的新方法。C# 允许派生类包含与基类方法名称相同的方法。基类方法必须定义为 virtual。如果派生类中的方法前面没有 new 或 override 关键字,则编译器将发出警告,该方法将有如存在 new 关键字一样执行操作。如果派生类中的方法前面带有 new 关键字,则该方法被定义为独立于基类中的方法。如果派生类中的方法前面带有 override 关键字,则派生类的对象将调用该方法,而不调用基类方法。可以从派生类中使用 base 关键字调用基类方法。override、virtual 和 new 关键字还可以用于属性、索引器和事件中。默认情况下,C# 方法不是虚方法 -- 如果将一种方法声明为虚方法,则继承该方法的任何类都可以实现其自己的版本。若要使方法成为虚方法,必须在基类的方法声明中使用 virtual 修饰符。然后,派生类可以使用 override 关键字重写基虚方法,或使用 new 关键字隐藏基类中的虚方法。如果 override 关键字和 new 关键字均未指定,编译器将发出警告,并且派生类中的方法将隐藏基类中的方法。有关更多信息,请参见编译器警告 CS0108。为了在实践中演示上述情况,我们暂时假定公司 A 创建了一个名为 GraphicsClass 的类,您的程序使用该类。GraphicsClass 类似如下:C#class GraphicsClass
{
public virtual void DrawLine() { }
public virtual void DrawPoint() { }
}
您的公司使用此类,并且您在添加新方法时将其用来派生自己的类:
C#
class YourDerivedGraphicsClass : GraphicsClass
{
public void DrawRectangle() { }
}
您在应用程序的使用过程中没有遇到任何问题,直到公司 A 发布了 GraphicsClass 的新版本,该新版本类似如下:
C#
class GraphicsClass
{
public virtual void DrawLine() { }
public virtual void DrawPoint() { }
public virtual void DrawRectangle() { }
}
现在,GraphicsClass 的新版本中包含了一个称为 DrawRectangle 的方法。最初,一切正常。新版本仍与旧版本二进制兼容 -- 即使在计算机系统中安装新类,部署的所有软件仍将继续工作。在您的派生类中,对方法 DrawRectangle 的任何现有调用将继续引用您的版本。
但是,一旦使用 GraphicsClass 的新版本重新编译应用程序,您将收到来自编译器的警告。有关更多信息,请参见编译器警告 CS0108。
此警告提示您需要考虑您的 DrawRectangle 方法在应用程序中的工作方式。
如果想用您的方法重写新的基类方法,请使用 override 关键字,如下所示:
C#
class YourDerivedGraphicsClass : GraphicsClass
{
public override void DrawRectangle() { }
}
override 关键字可确保派生自 YourDerivedGraphicsClass 的任何对象都将使用 DrawRectangle 的派生类版本。派生自 YourDerivedGraphicsClass 的对象仍可以使用 base 关键字访问 DrawRectangle 的基类版本,如下所示:
C#
base.DrawRectangle();
如果不想用您的方法重写新的基类方法,则应注意下面的事项。为避免在两种方法之间引起混淆,可以重命名您的方法。重命名方法可能很耗时且容易出错,而且在某些情况下并不实用。但是,如果您的项目相对较小,则可以使用 Visual Studio 的重构选项来重命名方法。有关更多信息,请参见重构类和类型。
或者,也可以通过在派生类定义中使用关键字 new 来防止出现该警告,如下所示:
C#
class YourDerivedGraphicsClass : GraphicsClass
{
public new void DrawRectangle() { }
}
使用 new 关键字告诉编译器您的定义将隐藏基类中包含的定义。这是默认行为。
重写和方法选择
当在类中指定方法时,如果有多个方法与调用兼容(例如,存在两种同名的方法,并且其参数与传递的参数兼容),则 C# 编译器将选择最佳方法进行调用。下面的方法将是兼容的:
C#
public class Derived : Base
{
public override void DoWork(int param) { }
public void DoWork(double param) { }
}
在 Derived 的一个实例中调用 DoWork 时,C# 编译器将首先尝试使该调用与最初在 Derived 上声明的 DoWork 版本兼容。重写方法不被视为是在类上进行声明的,而是在基类上声明的方法的新实现。仅当 C# 编译器无法将方法调用与 Derived 上的原始方法匹配时,它才尝试将该调用与具有相同名称和兼容参数的重写方法匹配。例如:
C#
int val = 5;
Derived d = new Derived();
d.DoWork(val); // Calls DoWork(double).
由于变量 val 可以隐式转换为 double 类型,因此 C# 编译器将调用 DoWork(double),而不是 DoWork(int)。有两种方法可以避免此情况。首先,避免将新方法声明为与虚方法同名。其次,可以通过将 Derived 的实例强制转换为 Base 来使 C# 编译器搜索基类方法列表,从而使其调用虚方法。由于是虚方法,因此将调用 Derived 上的 DoWork(int) 的实现。例如:
C#
((Base)d).DoWork(val); // Calls DoWork(int) on Derived.
c# override用法的更多相关文章
- Kotlin基础(三)类、对象和接口
类.对象和接口 一.定义类的继承结构 一)Kotlin中的接口 Kotlin的接口与Java8中相似,它们可以包含抽象方法的定义以及非抽象方法的实现,但它们不能包含任何状态. interface Cl ...
- Java高并发系列——检视阅读
Java高并发系列--检视阅读 参考 java高并发系列 liaoxuefeng Java教程 CompletableFuture AQS原理没讲,需要找资料补充. JUC中常见的集合原来没讲,比如C ...
- Java魔法堂:注解用法详解——@Override
一.前言 现在有Son和Parent两个类,且类型Son将会重写类型Parent的getName函数.但不幸的是由于码农大意,写成如下代码: public class Parent{ public S ...
- @Override在JDK1.5和JDK1.6中用法区别
@Override 注解在jdk1.5环境下,只能用于对基类(父类)的方法的重写.而不能用于对实现的接口的方法的实现.而在jdk1.6环境下,两者都适用.
- c#中virtual, abstract和override的区别和用法
virtual是把一个方法声明为虚方法,使派生类可重写此方法,一般建立的方法是不能够重写的,譬如类A中有个方法protected void method(){ 原代码....;}类B继承自类A,类B能 ...
- C#继承中的override(重写)与new(覆盖)用法
刚接触C#编程,我也是被override与new搞得晕头转向.于是花了点时间翻资料,看博客,终于算小有领悟,把学习笔记记录于此. 首先声明一个父类Animal类,与继承Animal的两个子类Dog类与 ...
- 【react表格组件】material-table 基本用法 & 组件override
教程: https://mbrn.github.io/material-table/#/ https://material-ui.com/api/table/ github: https://gith ...
- C# 关键字 virtual、override和new的用法
代码如下: class A { public void foo() { Console.WriteLine("A::foo()"); } public virtual void b ...
- C++ 虚函数表与多态 —— 关键字 override 的用法
override 仅能用于虚函数,他属于C++新特性,是重写覆盖的意思,他的存在仅仅是为了提高代码的可阅读性: 作用: 1. 提示程序的阅读者,这个函数是重写父类的功能. 2. 防止程序员在重写父类的 ...
随机推荐
- XF 列表视图事件
<?xml version="1.0" encoding="utf-8" ?><ContentPage xmlns="http:// ...
- WPF编游戏系列 之九 物品清单再优化
原文:WPF编游戏系列 之九 物品清单再优化 在"第三篇"和"第四篇"中通过用户控件和数据绑定功能对物品清单进行一些优化减少了部分C#代码,但感觉 ...
- wpf border内部元素内边角溢出问题 裁剪效果
效果图 <Grid> <Border BorderThickness=" BorderBrush="#3c4d72" CornerRadius=&quo ...
- C/C++使用libcurl库发送http请求(get和post可以用于请求html信息,也可以请求xml和json等串)
C++要实现http网络连接,需要借助第三方库,libcurl使用起来还是很方便的 环境:win32 + vs2015 如果要在Linux下使用,基本同理 1,下载编译libcurl 下载curl源码 ...
- requirejs教程(一):基本用法
介绍 RequireJS是一个非常小巧的JavaScript模块载入框架,是AMD规范最好的实现者之一.最新版本的RequireJS压缩后只有14K,堪称非常轻量.它还同时可以和其他的框架协同工作,使 ...
- 不能继承于QObject的类就一定不能使用信号槽?(用一个代理类进行发射就行了)
首先不能继承QObject的情况在开发中遇到得并不多,笔者在一年多的Qt项目开发中只遇到两三次.而且都是因为引进了第三方库导致编译过程中报错. 要想解决这个问题其实不难,因为笔者遇到的问题都是想定义一 ...
- 【Linux】使用crontab,让linux定时执行shell脚本
阅读目录 1. cron服务[Ubuntu环境] 2. crontab用法 3. vim编辑crontab文件 4.Cron各项描述 5.例子解释 Linux中,周期执行的任务一般由cron这个守护进 ...
- PHP阿里大鱼短信验证
PHP阿里大鱼短信验证 第一步 登陆阿里大于注册账号,在用户管理中心创建应用,确定AppKEY和App Secret还有配置签名 第二步 在应用管理中选择SDK下载,或者直接点击http://down ...
- C++虚函数与虚表
有一定面向对象知识的朋友对继承与多态一定很熟悉,C++想实现继承的话就要使用虚函数,那么什么是虚函数,其原理是什么,下面尽量给大家分析一下C++中其运行机制: 首先,基础,什么是虚函数,什么是多态? ...
- 由django请求生命周期延伸出的知识点大总结
django项目搭建见: https://www.cnblogs.com/dongxixi/p/10981577.html django请求生命周期图: 由浏览器发起请求开始 知识点1: 浏览器与服务 ...