C# virtual 是虚拟的含义,在 C# 语言中,默认情况下类中的成员都是非虚拟的,通常将类中的成员定义成虚拟的,表示这些成员将会在继承后重写其中的内容。

virtual 关键字能修饰方法、属性、索引器以及事件等,用到父类的成员中。

使用 virtual 关键字修饰属性和方法的语法形式如下。

//修饰属性

public  virtual  数据类型  属性名{get; set; }

//修饰方法

访问修饰符  virtual  返回值类型方法名

{

语句块;

}

需要注意的是,virtual 关键字不能修饰使用 static 修饰的成员。

此外,virtual 关键字既可以添加到访问修饰符的后面,也可以添加到访问修饰符的前面,但实际应用中习惯将该关键字放到访问修饰符的后面。

子类继承父类后能重写父类中的成员,重写的关键字是 override。

所谓重写是指子类和父类的成员定义一致,仅在子类中增加了 override 关键字修饰成员。

例如在父类中有一个求长方形面积的方法,方法定义如下。

publie int Area(int x, int y)

{

return x * y

}

在子类中重写该方法的代码如下。

public override int Area(int x,int y)

{

语句块;

return  整数类型的值;

}

在子类中重写父类中的方法后能改变方法体中的内容,但是方法的定义不能改变。

【实例 1】将上一节《C# base》中定义的 Person 类中的 Print 方法更改为虚拟的方法,分别用 Student 类和 Teacher 类继承 Person 类,并重写 Print 方法,打印出学生信息和教师信息。

为了减少重复的代码,在每个类中省略了属性部分的定义内容,仅保留 Print 方法部分的内容,实现的代码如下。

class Person

{

public virtual void Print()

{

Console.WriteLine("编号:"+ Id);

Console.WriteLine("姓名:"+ Name);

Console.WriteLine("性别:"+ Sex);

Console.WriteLine("身份证号:"+ Cardid);

Console.WriteLine("联系方式:"+ Tel);

}

}

class Student:Person

{

public override void Print()

{

Console.WriteLine("编号:"+ Id);

Console.WriteLine("姓名:"+ Name);

Console.WriteLine("性别:"+ Sex);

Console.WriteLine("身份证号:"+ Cardid);

Console.WriteLine("联系方式:"+ Tel);

Console.WriteLine("专业:"+ Major);

Console.WriteLine("年级:"+ Grade);

}

}

class Teacher:Person

{

public override void Print()

{

Console.WriteLine("编号:"+ Id);

Console.WriteLine("姓名:"+ Name);

Console.WriteLine("性别:"+ Sex);

Console.WriteLine("身份证号:"+ Cardid);

Console.WriteLine("联系方式:"+ Tel);

Console.WriteLine("专业:"+ Major);

Console.WriteLine("年级:"+ Grade);

}

}

通过上面的代码即可完成对 Person 类中 Print 方法的重写,在重写后的 Print 方法中能直接调用在 Person 类中定义的成员。

但读者会发现在 Person 类的 Print 中已经对 Person 中的相关属性编写了输出操作的代码,而每一个子类中又重复地编写了代码,造成代码的冗余,也没有体现出代码重用的特点。

如果能在重写父类方法的同时直接使用父类中已经编写过的内容就会方便很多。

在重写 Print 方法后仍然需要使用 base 关键字调用父类中的 Print 方法执行相应的操作。

【实例 2】改写实例 1 中的 Student 和 Teacher 类中重写的 Print 方法,使用 base 关键字调用父类中的 Print 方法。

根据题目要求,更改后的代码如下。

class Student:Person

{

public override void Print()

{

base.Print ();

Console.WriteLine("专业:"+ Major);

Console.WriteLine("年级:"+ Grade);

}

}

class Teacher:Person

{

public override void Print()

{

base.Print ();

Console.WriteLine("专业:"+ Major);

Console.WriteLine("年级:"+ Grade);

}

}

从上面的代码可以看出继承给程序带来的好处,不仅减少了代码的冗余,还增强了程序的可读性。

方法隐藏和重写方法有区别吗?这是很多初学者常问的问题。观察以下代码,思考结果会是什么?

class Program

{

static void Main(string[] args)

{

A a1 = new B();

a1.Print();

A a2 = new C();

a2.Print();

}

}

class A

{

public virtual void Print()

{

Console.WriteLine("A");

}

}

class B :A

{

public new void Print()

{

Console.WriteLine("B");

}

}

class C :A

{

public override void Print()

{

Console.WriteLine("C");

}

}

执行上面的代码,效果如下图所示。

从上面的执行效果可以看出,使用方法隐藏的方法调用的结果是父类 A 中 Print 方法中的内容,而使用方法重写的方法调用的结果是子类 C 中 Print 方法中的内容。

因此方法隐藏相当于在子类中定义新方法,而方法重写则是重新定义父类中方法的内容。

从上面的代码也可以看出,在“A a1=new B()”语句中 A 类是父类、B 类是子类,相当于将子类转换成父类,即隐式转换。

如果需要将父类转换成子类,则需要强制转换,并且在强制转换前需要先将所需的子类转换成父类,示例代码如下。

A a2=new C();

C c=(C) a2;

c.Print();

在上面的实例中,a2 是父类对象,然后将其强制转换成 C 类对象。

Object 类中的 ToString 方法能被类重写,并返回所需的字符串,通常将其用到类中返回类中属性的值。

在 Student 类中添加重写的 ToString 方法,代码如下。

class Student

{

public string Major{ get; set;}

public string Grade{ get; set;}

public void Print()

{

Console.WriteLine("专业:"+ Major);

Console.WriteLine("年级:"+ Grade);

}

public override string ToString()

{

return Major+","+Grade;

}

}

这样,在调用 Student 类中的 ToString 方法时即可获取专业和年级的值。

此外,除了 ToString 方法,在类中也可以重写 Equals 方法、GetHashCode 方法。

mysql virtual 关键字_C# virtual关键字详解相关推荐

  1. java this关键字的使用_Java this 关键字的使用方法详解

    Java this 关键字的使用方法详解 构造方法中的this关键字 构造方法是一个类的对象在通过new关键字创建时自动调用的,在程序中不能向调用其他方法一样通过方法名(也就是类名)来调用.但如果一个 ...

  2. mysql数据库表分区_MySQL数据库之MySQL的分区和分表详解

    本文主要向大家介绍了MySQL数据库之MySQL的分区和分表详解 ,通过具体的内容向大家展现,希望对大家学习MySQL数据库有所帮助. 1. 分区 MySQL中的分区是指将一个数据表按照某种规则(如时 ...

  3. linux下mysql数据库基础及客户端命令详解

    linux下mysql数据库基础及客户端命令详解 1.mysql数据库存储引擎: SHOW ENGINES;   #查看mysql支持的存储引擎 常见有如下两个存储引擎: MyISAM:每表三个文件: ...

  4. mysql启动参数(/etc/my.cnf)详解汇总

    mysql启动参数(/etc/my.cnf)详解汇总 MYSQL–my.cnf配置中文详解 basedir = path 使用给定目录作为根目录(安装目录). character-sets-dir = ...

  5. mysql 规则引擎_Drools规则引擎详解-常用的drl实例

    package droolsDemo //说明:每个 drl 都必须声明一个包名,这个包名与 Java 里面的不同,它不需要与文件夹的层次结构一致, //主要用于可以根据kmodule.xml中不同的 ...

  6. android json mysql_Android通过json向MySQL中读写数据的方法详解【读取篇】

    本文实例讲述了Android通过json向MySQL中读取数据的方法.分享给大家供大家参考,具体如下: 首先 要定义几个解析json的方法parseJsonMulti,代码如下: private vo ...

  7. php mysql PDO 查询操作的实例详解

    php mysql PDO 查询操作的实例详解 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 ...

  8. mysql语句性能开销检测profiling详解

    转载自 mysql语句性能开销检测profiling详解 之前我介绍过msyql查询优化explain检查命令的使用,explain主要是检查sql语句的基本性能,sql是否优秀,但不能查看具体的涉及 ...

  9. mysql切换用户sql语句,MySQL用户管理及SQL语句详解

    [(none)]>select user,host frommysql.user; #查询用户和主机+---------------+-----------+ | user | host | + ...

  10. mysql57数据库命令_MySQL 5.7 mysql command line client 使用命令详解

    MySQL 5.7 MySQL command line client 使用命令 1.输入密码:****** 2.ues mysql;使用Mysql 3.show databases;显示数据库 4. ...

最新文章

  1. Ubuntu10.04下gFtp2.0.19 远程客户端中文乱码解决方法
  2. jQuery操作input
  3. Serverless:为我们到底带来了什么
  4. 【计算理论】图灵机 ( 接受状态作用 | 格局 | 图灵机语言 | 图灵机设计复杂性 )
  5. 【SAP】自定义权限对象
  6. python基础教程:装饰器
  7. Python面向对象简单继承
  8. geth 以太坊钱包_以太坊Geth节点RPC API中文文档
  9. python怎么绘制渐变图_用Python画colorbar渐变图+修改刻度大小+修改渐变颜色
  10. 什么是敏捷_什么是敏捷?
  11. tableau两个不同的图合并_【书稿摘要】Tableau地图函数(下)
  12. python程序扩展名主要有-python文件的后缀名都有哪些?
  13. 申通回应被京东“封杀”;Kotlin 1.4.0 发布 | 极客头条
  14. 四则表达式求值—中缀表达式先转变成后缀表达式再求值python实现
  15. gcc详解以及静态,动态库的生成 2
  16. 【优化算法】天牛须搜索优化粒子群算法【含Matlab源码 1256期】
  17. android theme错误,关于android:您需要在此活动中使用Theme.AppCompat主题(或后代)。 更改为Theme.AppCompat会导致其他错误...
  18. UDP协议和TCP协议
  19. AVPlayerViewController支持横屏设置
  20. 华为服务器 修改为传统模式,电脑设置成服务器模式

热门文章

  1. 除了学历,你更需要有能力
  2. 前端工程师源码分享:html5 2d 扇子
  3. JAVA学习之路:不走弯路,就是捷径(二)
  4. python花数_python交换数字a b怎么用python画花朵
  5. 微软Technet安全技术中心,最新安全公告漏洞更新补丁发布。
  6. 数组两个整数相加 c语言,作业帮:给定一个整数数组,找出其中两个数相加等于目标值(去重set)...
  7. 程序员办公桌都是这么霸气的吗?扫码改需求?
  8. OPPO尝鲜android版本更新,OPPOColorOS系统国内首发安卓8.1,用户体验大升级
  9. 关于AirPlay和FLAC
  10. 游戏蓝牙耳机哪款比较好用?延迟超低的游戏蓝牙耳机推荐