C#中的virtual和override关键字
公众号「DotNet学习交流」,分享学习DotNet的点滴。
使用基类中的引用
代码如下:
class MyBaseClass //基类
{
public void Print()
{
Console.WriteLine("This is the base class");
}
}
class MyDerivedClass : MyBaseClass //派生类
{
new public void Print()
{
Console.WriteLine("This is the derived class");
}
}
internal class Program
{
static void Main(string[] args)
{
MyDerivedClass myDerived = new MyDerivedClass();
MyBaseClass myBaseClass = (MyBaseClass)myDerived; //转换成基类
myDerived.Print(); //从派生类部分调用Print方法
myBaseClass.Print(); //从基类部分调用Print方法
}
}
运行结果如下:

可以发现派生类调用的是派生类的方法,而基类调用的是基类的方法。
虚方法和覆写方法
虚方法可以使基类的引用访问“升至”派生类内,可以使基类引用调用派生类(derived class)的方法,只需满足下面的条件。
1、派生类的方法和基类的方法有相同的签名和返回类型。
2、基类的方法使用virtual标注。
3、派生类的方法使用override标注。
使用virtual和override的例子如下:
class MyBaseClass //基类
{
virtual public void Print()
{
Console.WriteLine("This is the base class");
}
}
class MyDerivedClass : MyBaseClass //派生类
{
override public void Print()
{
Console.WriteLine("This is the derived class");
}
}
class SecondDerivedClass : MyDerivedClass //派生类
{
override public void Print()
{
Console.WriteLine("This is the second derived class");
}
}
internal class Program
{
static void Main(string[] args)
{
SecondDerivedClass myDerived = new SecondDerivedClass();
MyBaseClass myBaseClass = (MyBaseClass)myDerived; //转换成基类
myDerived.Print(); //从派生类部分调用Print方法
myBaseClass.Print(); //从基类部分调用Print方法
}
}
运行结果如下所示:

不论是通过派生类调用还是通过基类调用,都会调用最高派生类中的方法,当通过基类调用时,调用被沿着继承层次向上传递,如下图所示:

SecondDerivedClass中的Print方法声明为override,它会覆写方法中的全部两个低派生级别的版本。
如果将SecondDerivedClass中的Print方法声明为new,代码如下所示:
class MyBaseClass //基类
{
virtual public void Print()
{
Console.WriteLine("This is the base class");
}
}
class MyDerivedClass : MyBaseClass //派生类
{
override public void Print()
{
Console.WriteLine("This is the derived class");
}
}
class SecondDerivedClass : MyDerivedClass //派生类
{
new public void Print()
{
Console.WriteLine("This is the second derived class");
}
}
internal class Program
{
static void Main(string[] args)
{
SecondDerivedClass myDerived = new SecondDerivedClass();
MyBaseClass myBaseClass = (MyBaseClass)myDerived; //转换成基类
myDerived.Print(); //从派生类部分调用Print方法
myBaseClass.Print(); //从基类部分调用Print方法
}
}
运行结果如下所示:

当Print方法通过SecondDerivedClass的引用调用时,SecondDerivedClass中的方法被执行,而当方法通过MyBaseClass的引用调用时,方法调用只向上传递了一级,到达类MyDerivedClass,在那里被执行。该过程的图示如下所示:

覆盖其他成员类型
其实属性事件以及索引器也是一样。
只读属性使用virtual/override的例子
代码如下:
class MyBaseClass //基类
{
private int _myInt = 5;
virtual public int MyProperty
{
get { return _myInt; }
}
}
class MyDerivedClass : MyBaseClass //派生类
{
private int _myInt = 10;
override public int MyProperty
{
get { return _myInt; }
}
}
internal class Program
{
static void Main(string[] args)
{
MyDerivedClass myDerived = new MyDerivedClass();
MyBaseClass myBaseClass = (MyBaseClass)myDerived; //转换成基类
Console.WriteLine(myDerived.MyProperty);
Console.WriteLine(myBaseClass.MyProperty);
}
}
运行结果如下所示:

C#中的virtual和override关键字的更多相关文章
- C#中的Virtual、Override和new关键词理解
来源:http://blog.csdn.net/jackiezhw/article/details/2673992 在 C# 中,派生类可以包含与基类方法同名的方法. 基类方法必须定义为 virtua ...
- 【c# 学习笔记】使用virtual和override关键字实现方法重写
只有基类成员声明为virtual或abstract时,才能被派生类重写:而如果子类想改变虚方法的实现行为,则必须使用override关键字. public class Animal { private ...
- c#中关于virtual,override和new的理解
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Cons ...
- c#和java中的方法覆盖——virtual、override、new
多态和覆盖 多态是面向对象编程中最为重要的概念之一,而覆盖又是体现多态最重要的方面.对于像c#和java这样的面向对象编程的语言来说,实现了在编译时只检查接口是否具备,而不需关心最终的实现,即最终的实 ...
- 接口与virtual,override,new关键字
一,类继承接口 1,首先我们定义一个简单的ITeacher接口,并定义一个Professor类继承它. public interface ITeacher { void Print(); } publ ...
- sealed,new,virtual,abstract与override关键字的区别?
1. sealed——“断子绝孙” 密封类不能被继承.密封方法可以重写基类中的方法,但其本身不能在任何派生类中进一步重写.当应用于方法或属性时,sealed修饰符必须始终与override一起使用. ...
- JAVA - 请说明”static”关键字是什么意思?Java中是否可以覆盖(override)一个private或者是static的方法?
请说明"static"关键字是什么意思?Java中是否可以覆盖(override)一个private或者是static的方法? "static"关键字表明一个成 ...
- C++中的Overload、Override和Overwrite
在C++语言中有一组基础的概念一直都容易混淆:Overload.Override和Overwrite分别表示什么意思?下面把这三个概念整理一下: 1. Overload(重载) 重载的概念最好理解,在 ...
- C# virtual和override
本文转载来自于:http://bollaxu.iteye.com/blog/1662855 在函数的声明中,当有“virtual”修饰的时候,和没有virtual有什么区别呢?最重要的一点就是调用实例 ...
- C#--virtual,abstract,override,new,sealed
virtual:使用此关键字,可以使其在派生类中被重写. abstract:抽象方法,由子类重写,或继续为抽象方法存在,并由其子子类实现. override: 重写父类方法,属性,或事件的抽象实现或虚 ...
随机推荐
- 图解算法,原理逐步揭开「GitHub 热点速览」
想必每个面过大厂的小伙伴都被考过算法,那么有没有更快了解算法的方式呢?这是一个老项目,hello-algo 用图解的方式让你了解运行原理.此外,SQL 闯关自学项目也是一个让你能好好掌握 SQL 技术 ...
- Spring Cloud OpenFeign 的使用及踩坑指南
目录 Feign 和OpenFeign Feign OpenFeign openFeign的优势 OpenFeign应用 1. 导入依赖 2. 使用 3. 日志配置 4. 数据压缩 OpenFeign ...
- 【译】通过 GitHub Copilot Chat 简化代码优化和调试(AI 辅助编程)
今年3月,我们宣布了 Visual Studio 2022 的 GitHub Copilot Chat.通过 Chat, Copilot 已经超越了代码补全,提供了对代码工作原理的深入分析和解释.它支 ...
- Web攻防--Java_SQL注入--XXE注入-- SSTI模板注入--SPEL表达式注入
预编译 编译器在编译sql语句时,会依次进行词法分析.语法分析.语义分析等操作, 预编译技术会让数据库跳过编译阶段,也就无法就进行词法分析,关键字不会被拆开,注入语句也就不会被识别为SQL的关键字,从 ...
- MySQL系列2:InnoDB存储引擎
1. 架构回顾 上一篇我们讲解了MySQL的逻辑架构,重新回顾一下,用一张新的图来认识一下该架构. 整体架构分为service层与存储引擎层,请求交给连接池后,由后台线程处理,并将请求转发给SQL接口 ...
- Note -「Maths」Euler 筛筛积性函数
Part. 1 Preface 这个东西是我在做 JZPTAB 的时候 LYC 给我讲的. 然后发现这是个通法,就写一写. 本文除了例题所有代码均未经过编译,仅作为参考. Part. 2 Untitl ...
- Github 组合搜索开源项目 (超详细)
例如搜索 Spring Boot 相关项目 spring boot (最简单最常用) in:name spring boot (匹配项目名字) in:name spring boot stars: ...
- .NET应用如何防止被反编译
前言 前段时间分享了两篇关于.NET反编译相关的文章,然后文章留言区就有小伙伴提问:如何防止被反编译?因此本篇文章我们就来讲讲.NET应用如何防止被反编译..NET反编译相关的文章可以看如下文章: 4 ...
- 9. 用Rust手把手编写一个wmproxy(代理,内网穿透等), HTTP2改造篇之HPACK示例, 了解http2头信息如何处理
9. 用Rust手把手编写一个wmproxy(代理,内网穿透等), HTTP2改造篇之HPACK示例, 了解http2头信息如何处理 项目 ++wmproxy++ gite: https://gite ...
- OpenJDK17-JVM源码阅读-ZGC-并发标记
1.ZGC简介 1.1 介绍 ZGC 是一款低延迟的垃圾回收器,是 Java 垃圾收集技术的最前沿,理解了 ZGC,那么便可以说理解了 java 最前沿的垃圾收集技术. 从 JDK11 中作为试验特性 ...