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. Asp.Net Memcached安装配置使用、安全性

    Memcached安装配置使用  一,准备        你需要有一下软件:       VS.NET(05/08)       SQLSERVER       memcached服务器端以及客户端类 ...

  2. iis 配置php

    1.CGI全称是“公共网关接口”(Common Gateway Interface),HTTP服务器与你的或其它机器上的程序进行“交谈”的一种工具,其程序须运行在网络服务器上. CGI可以用任何一种语 ...

  3. Maven java项目管理工具

    Maven java项目管理工具 1.安装maven 下载最新的maven 下载地址 http://maven.apache.org/download.cgi 传到要安装的目录 例如/opt/下 # ...

  4. BZOJ 4311: 向量( 按时间分治 + 线段树 )

    离线, 然后按时间分治, 每个向量都有出现时间[l, r], 直接插入时间线段树(一个向量只会影响O(logN)数量级的线段树节点). 在线段树每个节点弄出凸壳然后二分. 时间复杂度O(Nlog^2N ...

  5. leetcode Palindrome Number python

    class Solution(object): def isPalindrome(self, x): """ :type x: int :rtype: bool &quo ...

  6. ;(function( $, window, undefined ){ }(jQuery,window))为何需要往里面传$,window,undefined这些参数

    (function( $, jQuery , undefined ) {})(jQuery); 为什么要将window和undefined作为参数传给它? 因为 ecmascript 执行JS代码是从 ...

  7. codeforces 242E. XOR on Segment 线段树

    题目链接 给n个数, 两种操作, 一种是求区间内的数的和, 一种是将区间内的数异或x. 异或x没有什么思路, 单个异或肯定超时, 区间异或也没有办法做....后来才知道可以按位建线段树, 这样建20棵 ...

  8. zoj 2587 Unique Attack 最小割判定

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

  9. 在Windows环境下部署Axis2/C服务

    Apache Axis2/C是C语言实现的网络服务引擎,基于Axis2架构,支持SOAP1.1和SOAP1.2协议,并且支持RESTful风格的Web service. 下面是本人在Windows 7 ...

  10. smarty如何处理状态值的显示

    比如状态,有效或者无效.这个数据库中保存的是1或者2这样的字段. 显示在列表的时候不能是1或者2吧. 以前,我都是在后台foreach,处理的.感觉处理之后,前台就不灵活了.这个值就被替换成了文字. ...