两者区别在于,虚函数总能调用到正确的,即根据当前类型来调用;而new并不是这样。
1. 采用了virtual声明的函数(虚函数)子类重写的时候会调用子类对象的方法
因此在通过基类进行转化的时候,虚函数会根据对象真正类型,而调用相应的函数;
例如:
A objA = new B();
objA.dosomething();//Call B::dosomething method, not A::dosomething
2.没声明为虚函数
而对于new来说,函数的调用不会产生多态,会根据定义类型而进行调用
例如:
A objA = new B();
objA.dosomething();//Call A::dosomething method, not B::dosomething
因此前者属于多态,属于后绑定,需要在运行的时候才能知道调用的是哪个类型方法;而后者属于静态绑定,在编译的时候已经确定了调用的类型方法。
如果还没明白请看一下代码
class 虚方法
{
public static void Main()
{
A aa = new B(); //用子类对象来实例化父类
//一下是用父类对象去调用其方法 getType 是没用virtual修饰的 getType2是用virtual修饰的
Console.WriteLine(aa.getType() + " " + aa.getTyep2()); // A BB
Console.ReadLine();
}
}
public class A
{
public string getType()
{
return "A";
}
public virtual string getTyep2()
{
return "AA";
}
}
public class B : A //B继承自A
{
//public string getType()
//{
// return "b";
//}
public new string getType()
{
return "B";
} //前面两种方式 隐藏基类的getType方法是一样的效果,但是第一种方法编译器会有一个警告 提示你是否有意隐藏基类的方法
public override string getTyep2()
{
return "BB";
}
}
输出结果: A BB
从上面可以看出 声明虚函数 子类重写该方法 用子类去实例化父类的时候 调用的会是子类相应的方法。
其次的 如果父类方法没有用virtual来修饰则 子类不可以用override 来重写该方法 只可以用new关键字来隐藏父类的方法,或者什么都不加也可以。但最后面一种情况编译器会给与一个警告。