公众号「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关键字的更多相关文章

  1. C#中的Virtual、Override和new关键词理解

    来源:http://blog.csdn.net/jackiezhw/article/details/2673992 在 C# 中,派生类可以包含与基类方法同名的方法. 基类方法必须定义为 virtua ...

  2. 【c# 学习笔记】使用virtual和override关键字实现方法重写

    只有基类成员声明为virtual或abstract时,才能被派生类重写:而如果子类想改变虚方法的实现行为,则必须使用override关键字. public class Animal { private ...

  3. c#中关于virtual,override和new的理解

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Cons ...

  4. c#和java中的方法覆盖——virtual、override、new

    多态和覆盖 多态是面向对象编程中最为重要的概念之一,而覆盖又是体现多态最重要的方面.对于像c#和java这样的面向对象编程的语言来说,实现了在编译时只检查接口是否具备,而不需关心最终的实现,即最终的实 ...

  5. 接口与virtual,override,new关键字

    一,类继承接口 1,首先我们定义一个简单的ITeacher接口,并定义一个Professor类继承它. public interface ITeacher { void Print(); } publ ...

  6. sealed,new,virtual,abstract与override关键字的区别?

    1. sealed——“断子绝孙” 密封类不能被继承.密封方法可以重写基类中的方法,但其本身不能在任何派生类中进一步重写.当应用于方法或属性时,sealed修饰符必须始终与override一起使用. ...

  7. JAVA - 请说明”static”关键字是什么意思?Java中是否可以覆盖(override)一个private或者是static的方法?

    请说明"static"关键字是什么意思?Java中是否可以覆盖(override)一个private或者是static的方法? "static"关键字表明一个成 ...

  8. C++中的Overload、Override和Overwrite

    在C++语言中有一组基础的概念一直都容易混淆:Overload.Override和Overwrite分别表示什么意思?下面把这三个概念整理一下: 1. Overload(重载) 重载的概念最好理解,在 ...

  9. C# virtual和override

    本文转载来自于:http://bollaxu.iteye.com/blog/1662855 在函数的声明中,当有“virtual”修饰的时候,和没有virtual有什么区别呢?最重要的一点就是调用实例 ...

  10. C#--virtual,abstract,override,new,sealed

    virtual:使用此关键字,可以使其在派生类中被重写. abstract:抽象方法,由子类重写,或继续为抽象方法存在,并由其子子类实现. override: 重写父类方法,属性,或事件的抽象实现或虚 ...

随机推荐

  1. (转)[Android测试] Android Studio+Appium+Java+Windows 自动化测试之二:Appium环境安装搭建

    一.需要下载安装的东西 1. 文件下载 网上也有挺多安装教程的,这里我提供我的安装方法.Win10 64位.一些文件我在后面打包. 2016.9.12号本人安装记录. SDK: 由于我是搞Androi ...

  2. vite 找不到依赖模块:[plugin:vite:dep-pre-bundle]

    问题描述: 运行项目时,出现[plugin:vite:dep-pre-bundle] 错误.这种问题一般为依赖的包未正常配置相关字段,导致vite无法找到包的入口. 遇到这种模块内.找不到引用模块的, ...

  3. 关于Vue的就地更新策略的解析

    在Vue中使用v-for渲染列表时,默认使用就地更新策略.该策略默认是基于索引的,规定在列表绑定的数据元素顺序变化时,不会重新创建整个列表,而只是更新对应DOM元素上的数据.以下代码实现了一个TODO ...

  4. python 运行环境变为 pytest in (for) xxx.py原因

    因为本人的自定义函数名称开头为test,在.py文件内我用了unittest框架,所以环境随着变化了. 修改回去很简单,只要不使用test开头或者换个文件夹.

  5. Strategy Pattern and Polymorphism —— Behavioral Class

    策略模式着重于封装和替换 不同的算法或行为,以便在运行时进行选择. Simple example - Computer and USB interface 现代人对计算机.USB接口还有各种设备之间的 ...

  6. 全局多项式(趋势面)与IDW逆距离加权插值:MATLAB代码

      本文介绍基于MATLAB实现全局多项式插值法与逆距离加权法的空间插值的方法,并对不同插值方法结果加以对比分析. 目录 1 背景知识 2 实际操作部分 2.1 空间数据读取 2.2 异常数据剔除 2 ...

  7. 用OLED屏幕播放视频(1): 项目介绍

    下面的系列文章记录了如何使用一块linux开发扳和一块OLED屏幕实现视频的播放: 项目介绍 为OLED屏幕开发I2C驱动 使用cuda编程加速视频处理 这篇文章主要对项目的实现做整体的介绍, 包括硬 ...

  8. SpingCloud:Gateway+Nginx+Stomp+Minio构建聊天室并进行文件传输

    注:本人使用阿里云服务器(安装mino)+本地虚拟机(安装nginx)进行,理论上完全在本地进行也可以. 1.前期准备: 1.将本地虚拟机设置为静态ip且能ping通外网,参考网址:https://w ...

  9. JDK17和JDK8在windows上同时安装方便切换

    参考:https://blog.csdn.net/chencaw/article/details/121674479 一.JDK8的安装 1.电脑上已经安装了JDK8,安装主要步骤如下 (1)创建JA ...

  10. LUA的一些工具备份

    table.unpack遇到的问题 做了个中转的服务, socket+json 传递数据, 通过 {...} 封装不定参数然后 json.encode 传递到其他服务器, 然后其他服务器 json.d ...