C#允许派生类中的方法与基类中方法具有相同的签名:基类中使用关键字virtual定义虚方法;然后派生类中使用关键字override来重写方法,或使用关键字new来覆盖方法(隐藏方法)。

重写方法用相同的签名重写所继承的虚方法。虚方法声明用于引入新方法,而重写方法或隐藏方法声明则是用于使现有的继承虚方法专用化(通过提供该方法的新实现)

注意:如果签名相同的方法在基类和派生类都进行了声明,但该方法没有声明为virtual和override/new,则派生类方法就会隐藏基类方法,但系统编译时会产生警告信息。因为隐藏方法会存在为给定类的实例调用错误方法的危险,故应该显示地定义隐藏方法。

调用虚方法时,将首先检查该对象的运行时类型,并调用派生类中的该重写成员。如果没有派生类重写该成员,则调用其原始数据。

默认情况下,C#方法是非虚拟的。不能重写非虚方法,重写非虚方法将导致编译错误。

除了类方法外,还可以使用virtual关键字其他类成员以定义虚成员,包括属性【无参属性】、索引器【含参属性】或事件声明。虚拟成员的实现可在派生类使用关键字override来重写;或使用关键字new来覆盖。

注意:virtual 修饰符不能与static、abstract、private或override修饰符一起使用。

例:

虚方法,重写方法和隐藏方法示例:Dimensions类包含x,y两个坐标和Area()虚方法。Dimensions类的派生类(Circle、Cylinder和Sphere)均重写了基类的虚方法Area()以实现不同图形表面积的计算。调用虚方法Area()时,将根据此方法关联的运行时对象调用适当的Area()实现,为每个图形计算并显示适当的面积。

   1:  namespace ConsoleApplication2
   2:  {
   3:   
   4:   
   5:   
   6:      public class Dimensions
   7:      {
   8:   
   9:          public const double PI = Math.PI;
  10:          protected double x, y;
  11:          public Dimensions()
  12:          {
  13:   
  14:          }
  15:   
  16:          public Dimensions(double x, double y)
  17:          {
  18:              this.x = x;
  19:              this.y = y;
  20:          }
  21:   
  22:          public virtual double Area()
  23:          {
  24:              return x * y;
  25:          }
  26:   
  27:      }
  28:   
  29:      public class Circle : Dimensions          //派生类:圆
  30:      {
  31:          public Circle(double r)
  32:              : base(r, 0)
  33:          {
  34:   
  35:          }
  36:   
  37:          public override double Area()
  38:          {
  39:              //园的面积
  40:              return PI * x * x;
  41:          }
  42:      }
  43:      public class Sphere : Dimensions          //派生类:球体
  44:      {
  45:          public Sphere(double r)
  46:              : base(r, 0)
  47:          {
  48:   
  49:          }
  50:   
  51:          public override double Area()
  52:          {
  53:              //球体的表面积
  54:              return 4 * PI * x * x;
  55:          }
  56:      }
  57:      public class Cylinder : Dimensions          //派生类:圆柱体
  58:      {
  59:          public Cylinder(double r)
  60:              : base(r, 0)
  61:          {
  62:   
  63:          }
  64:   
  65:          public override double Area()
  66:          {
  67:              //圆柱体的表面积
  68:              return 2 * PI * x * x + 2 * PI * x * y;
  69:          }
  70:      }
  71:   
  72:      public class Program
  73:      {
  74:   
  75:   
  76:          static void Main(string[] args)
  77:          {
  78:              double r = 3.0, h = 5.0;
  79:              Dimensions c = new Circle(r);           //圆
  80:   
  81:              Dimensions s = new Sphere(r);           //球体
  82:   
  83:   
  84:              Dimensions l = new Cylinder(r);         //圆柱体
  85:   
  86:              //显示各种不同形状的表面积
  87:   
  88:              Console.WriteLine("圆的面积={0:f2}",c.Area());
  89:              Console.WriteLine("球体的面积={0:f2}", s.Area());
  90:              Console.WriteLine("圆柱体的面积={0:f2}", l.Area());
  91:              Console.ReadKey();
  92:          }
  93:      }
  94:  }

C# 读书笔记之访问虚方法、重写方法和隐藏方法的更多相关文章

  1. C# 读书笔记之访问关键字this和base

    this 关键字引用类的当前实例.静态成员方法中不能使用this关键字,this关键字只能在实例构造函数.实例方法或实例访问器中使用. base 关键字用于从派生类中访问基类的成员. 指定创建派生类实 ...

  2. 《ASP.NET MVC高级编程(4版)》读书笔记(5)表单和HTML辅助方法

    5.1 表单使用 5.1.1 action 和 method 特性 <form action="/Home/Index">     <input name=&qu ...

  3. Effective Java 读书笔记之二 对于所有对象都通用的方法

    尽管Object是一个具体的类,但设计它主要是为了扩展.它的所有非final方法都有明确的通用约定.任何一个类在override时,必须遵守这些通用约定. 一.覆盖equals时请遵守通用的约定 1. ...

  4. C# 方法重载 overload、方法重写 override、隐藏 new

    一.重载:同一个作用域内发生(比如一个类里面),定义一系列同名方法,但是方法的参数列表不同.这样才能通过传递不同的参数来决定到底调用哪一个. 值得注意的是,方法重载只有通过参数不同来判断调用哪个方法, ...

  5. 【原】自定义UINavigationItem的两种方法以及相应的隐藏方法

    第一种: UIImage *searchimage=[UIImage imageNamed:@"search.png"]; UIBarButtonItem *barbtn=[[[U ...

  6. 自定义UINavigationItem的两种方法以及相应的隐藏方法

    第一种: UIImage *searchimage=[UIImage imageNamed:@"search.png"]; UIBarButtonItem *barbtn=[[[U ...

  7. Struts 2读书笔记-----Action访问Servlet API

    Action访问Servlet API Struts2中的Action并没有和任何Servlet API耦合,这样框架更具灵活性,更易测试. 对于Web应用的控制器而言,不访问ServletAPI是几 ...

  8. 《大型网站系统与JAVA中间件实践》读书笔记-数据访问层

    数据访问层 5.1.2数据库垂直/水平拆分的困难 随着网站业务的快速发展,数据量和访问量不断上升,数据库的压力越来越大. 更换更好的硬件(Scale Up)是一种解决方案,而且在我们能付得起硬件费用并 ...

  9. 【读书笔记】iOS-安全地传输用户密码的方法

    正确做法:事先生成一对用于加密的公私钥,客户端在登录时,使用公钥将用户的密码加密后,将密文传输到服务器.服务器使用私钥将密码解密,然后加盐之后多次请求MD5,之后再和服务器原来存储的用同样方法处理过的 ...

随机推荐

  1. 动态加载 js

    要实现动态加载JS脚本有4种方法: 1.直接document.write <script language="javascript"> document.write(& ...

  2. PHP去除Notice警告提示

    最近刚接触PHP,开发过程中可能会遇到Notice: Use of undefined ……这样的警告提示,可能是代码写的不太规范, 有两种解决途径:关闭 PHP 提示的方法, 搜索php.ini:e ...

  3. shell检测interface是否已分配ip,qt调用shell脚本

    #include <QCoreApplication>#include <QDebug>#include <QTextStream>#include <QDi ...

  4. shell 守护进程

    #!/bin/sh #守护进程,接受2个参数 #para CMD 执行的命令 #pare ID 唯一标识改命令 if [ "$1" = "" -o " ...

  5. Spring总结——控制反转,注入(配置和注解两种方式)

    一.Spring的容器: 1.什么是控制反转:传统的方法,当某个java对象A需要调用对象B时,是由调用者(对象A)通过new关键字来创建对象B的(也可以说类A依赖类B),而在Spring中,则是由s ...

  6. day3_python学习笔记_chapter5_数字

    1. 整形的表示范围-2^32~2^32 - 1 : 长整形表示:aLong = 99999L 2. 复数的属性, num.real,该复数的实部, num.imag,该复数的虚部.num.conju ...

  7. php数组使用技巧及操作总结

    数组,可以说是PHP的数据应用中较重要的一种方式.PHP的数组函数众多,下面是一些小结,借此记之,便于以后鉴之. 1. 数组定义 数组的定义使用 array()方式定义,可以定义空数组:<?ph ...

  8. zoj 2587 Unique Attack 最小割判定

    题目链接 让你判断最小割是否唯一. 判断方法是, 先求一遍最大流, 然后从源点dfs一次, 搜索未饱和边的数目. 从汇点dfs一次, 同样也是搜索未饱和边的数目, 看总和是否等于n. 如果等于n那么唯 ...

  9. Linux例行工作crontab

    第一步编辑要定时执行的脚本: myScript.sh myScript.sh的内容为:touch /root/`date +%F' '%T`.txt 为myScript.sh增加可执行权限:chmod ...

  10. 腾讯出品的抓包工具Rythem

    Mac下一直没有fiddler这样好用的抓包工具,Charles要收费,难免不爽,昨天调研国内项目的时候,看到腾讯开源了一款抓包工具Rythem,试用了一下,基本配置无问题,但是通配符方面不太搞的定. ...