赞
踩
virtual 关键字用于修饰方法、属性、索引器或事件声明,并且允许在派生类中重写这些对象。例如,此方法可被任何继承它的类重写。
当类中的方法声明前加上了virtual修饰符,我们称之为虚方法,反之为非虚。
若希望或预料到基类的这个方法在将来的派生类中会被重写(override ),则此方法必须被声明为 virtual。
调用虚方法时,将为重写成员检查该对象的运行时类型。将调用大部分派生类中的该重写成员,如果没有派生类重写该成员,则它可能是原始成员。
默认情况下,方法是非虚拟的。不能重写非虚方法。
virtual 修饰符不能与 static、abstract, private 或 override 修饰符一起使用。
除了声明和调用语法不同外,虚拟属性的行为与抽象方法一样。
· 在静态属性上使用 virtual 修饰符是错误的。
· 通过包括使用 override 修饰符的属性声明,可在派生类中重写虚拟继承属性。
virtual 修饰符 返回的数据类型方法名(参数表)
{
方法体
}
对于非虚的方法,无论被其所在类的实例调用,还是被这个类的派生类的实例调用,方法的执行方式不变。而对于虚方法,它的执行
方式可以被派生类改变,这种改变是通过方法的重载来实现的。
override 修饰符 返回的数据类型方法名(参数表)
{
方法体
}
override 重写继承自基类的 virtural 方法,可以理解为拆掉老房子,在原址上建新房子,老房子再也找不到了(基类方法永远调用不到了)。
都可以对基类成员进行隐藏,都可以用base关键字调用基类的成员
new和override的不同点:
用override的基类的方法必须要用virtual,而new不必要
本质区别在于当派生类对象作为基类类型使用时,override 的执行派生类方法,new 的执行基类方法。如果作为派生类类型调用,则都是执行 override 或 new 之后的。
override 重写继承自基类的 virtural 方法,可以理解为拆掉老房子,在原址上建新房子,老房子再也找不到了(基类方法永远调用不到了)。
new 隐藏继承自基类的 virtual 方法,老房子还留着,在旁边盖个新房,想住新房住新房(作为派生类对象调用),想住老房住老房(作为基类对象调用)。
当派生类中出现与基类同名的方法,而此方法前面未加 override 或 new 修饰符时,编译器会报警告,但不报错,真正执行时等同于加了 new。
下面是代码实现:
- public interface I_9_A
- {
- int Age { get;set;}
- string GetName();
- string GetPwd();
- }
- /// <summary>
- /// 下面这个类继承了A接口,并实现了里面的全部成员
- /// </summary>
- public class I_9_L_1 : I_9_A
- {
- protected int age;
- protected string name;
- protected string pwd;
-
- public I_9_L_1()
- {
- age = 28;
- name = "提高班";
- pwd = "tgb";
- }
-
- public int Age
- {
- get { return age; }
- set { age = value; }
- }
-
- public string GetName()
- {
- return name;
- }
- public string GetPwd()
- {
- return pwd;
- }
- }
- public class I_9_L_2 : I_9_L_1
- {
- public new string GetName()
- {
- return ":" + name;
- }
- public new string GetPwd()
- {
- return "密码:" + pwd;
- }
- }
-
- /**当我们看了上面的演示以后会发现一个很严重的问题,
- * 我们明明就调用的2这个类,可为什么方法却依然是1哪个类的呢?
- * 原因就在2这个类虽然是复写了1类中的方法,但是他并没有去改写1类中的方法
- **/
- ///
- /// <summary>
- /// 下面这个类继承了A接口,并实现了里面的全部成员
- /// </summary>
- public class I_9_L_3 : I_9_L_1
- {
- protected int age;
- protected string name;
- protected string pwd;
-
- public I_9_L_3(int a, string n, string p)
- {
- age = a;
- name = n;
- pwd = p;
- }
-
- public int Age
- {
- get { return age; }
- set { age = value; }
- }
-
- public virtual string GetName()
- {
- return name;
- }
- public virtual string GetPwd()
- {
- return pwd;
- }
- }
- public class I_9_L_4 : I_9_L_3
- {
- public I_9_L_4(int a, string n, string p)
- : base(a, n, p)
- {
- age = a;
- name = n;
- pwd = p;
- }
- public override string GetName()
- {
- return "我是:" + name;
- }
- public override string GetPwd()
- {
- return "密码是:" + pwd;
- }
- }
-
- /**
- * 其实这个例题理解起来不难的,首先我们知道他整个的运行顺序
- * 然后就是,如果发现不是虚方法,那么就直接调用了,但是如果是他就会继续往下找,一直找到不是虚的位置.
- *
- * 我们这个例题说完了,不知道你有没有想起我们前面说过的一个问题,就是显示实现的无法使用修饰符,
- * 既然不能使用修饰符,那virtual也没法用,难道显示实现的方法就不能使用虚方法了吗?
- *
- * 答案是否定的,呵呵
- *
- * 我们可以在这个显示实现中调用另一个方法嘛,哈哈,然后这个被调用的方法再是虚方法,我想法律不会不允许吧
- * **/
- ///
- /// <summary>
- /// 下面这个类继承了A接口,并实现了里面的全部成员
- /// </summary>
- public class I_9_L_5 : I_9_A
- {
- protected int age;
- protected string name;
- protected string pwd;
-
- public I_9_L_5(int a, string n, string p)
- {
- age = a;
- name = n;
- pwd = p;
- }
-
- public int Age
- {
- get { return age; }
- set { age = value; }
- }
-
- public string GetName()
- {
- return name;
- }
- public string GetPwd()
- {
- return pwd;
- }
- }
- public class I_9_L_6 : I_9_L_5,I_9_A
- {
- public I_9_L_6(int a, string n, string p)
- : base(a, n, p)
- {
- age = a;
- name = n;
- pwd = p;
- }
- public string GetName()
- {
- return "我是:" + name;
- }
- public string GetPwd()
- {
- return "密码是:" + pwd;
- }
- }
- }
---------------------------原文参考CSDN和天轰穿视频
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。