Virtual表示虚拟的含义但在C#中默认的成员是非虚拟的,通常将类中的成员定义为虚拟的,表示这些成员在继承后 可以被重写其中的内容
Virtual关键字可以修饰方法、属性、索引器 以及事件等用到父类的成员中
使用Virtual 关键字修饰属性和方法的语法形式如下
//修饰属性
Public virtual 数据类型 属性名 {get;set;}
//修饰方法
访问修饰符 virtual 返回值类型方法
{
语句块
}
例子:
- 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);
- }
- }
但对于以上代码 需要消除代码冗余,在这使用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 方法。



