Virtual 和 非 virtual

从http://hacker.cnblogs.com/archive/2004/08/10/31774.aspx看到了Virtual的用法,结合自己的理解整理如下:

 

1. 如果方法不是virtual的,编译器就使用声明的类对应的类型,也就是说,不是virtual的,在编译时候,就定了。比如下面的例子:子类的方法都没有执行,执行的全部都是父类的方法。

运行的结果:

parent

son

daughter

 

using System;
using System.Collections.Generic;
using System.Text;

namespace VirtualTest
{

    public class ClassParent
    {
        public string s1;
        public void VirFun()
        {
            Console.WriteLine(s1);
        }
    }


    public class ClassSon : ClassParent
    {
        public new void VirFun()
        {
            Console.WriteLine("son:" + s1);
        }

    }
    public class ClassDaughter : ClassParent
    {
        public new void VirFun()
        {
            Console.WriteLine("girl:" + s1);
        }
    }


    public class Test
    {
        public static void Main()
        {
            ClassParent a = new ClassParent();
            a.s1 = "parent";
            a.VirFun();
            ClassParent b = new ClassSon();
            b.s1 = "son";
            b.VirFun();
            ClassParent c = new ClassDaughter();
            c.s1 = "daughter";
            c.VirFun();
            Console.Read();
        }
    }
}

 

2. 如果方法是Virtual的,然后子类使用了override,编译器就生产代码。然后,在运行的时候,进行检测,看对象属于哪个类,然后调用这个类的方法。这个是最常用的方法,基本上所有书上说的就是这个,我就不多此一举了。

 

3.3如果一个父类的方法是virtual,子类不是用override,而是用new来覆盖了,那么运行子类的时候,还是执行声明的类的方法。比如下面的例子中,daughter类对象就是。

运行结果:

parent

son: son

daughter

 

using System;
using System.Collections.Generic;
using System.Text;

namespace VirtualTest
{

    public class ClassParent
    {
        public string s1;
        public virtual void VirFun()
        {
            Console.WriteLine(s1);
        }
    }


    public class ClassSon : ClassParent
    {
        public override void VirFun()
        {
            Console.WriteLine("son:" + s1);
        }

    }
    public class ClassDaughter : ClassParent
    {
        public new void VirFun()
        {
            Console.WriteLine("girl:" + s1);
        }
    }


    public class Test
    {
        public static void Main()
        {
            ClassParent a = new ClassParent();
            a.s1 = "parent";
            a.VirFun();
            ClassParent b = new ClassSon();
            b.s1 = "son";
            b.VirFun();
            ClassParent c = new ClassDaughter();
            c.s1 = "daughter";
            c.VirFun();
            Console.Read();
        }
    }
}

补充:
关于1:无virtual时,编译期就确定方法的类型了。也即:无法实现多态了。
关于2:有vitual时
方法在运行时确定类型。可以实现多态 只要子类override基类的vitual方法。
关于3:
new与virtual并没有必然的联系。从字面上看,new声明的方法是一个“新”方法,与基类完全没有关系(虽然不幸与基类的某个方法同名同 参)。也即:通过向上转型(如:基类 引用名=new 子类())得到的引用将无法看到子类中new出来的方法。所以会出现第3点中的结果。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值