C#:abstract virual 区别 和 相同之处
1:
abstract 方法 必须 没有实现, 且必须被继承类(如果该类不是抽象类的话)实现.
声明了abstract方法的类必须为abstract类,abstract类可以有其他非抽象方法.
2:
virual方法必须有实现.别不必被继承类实现.
声明了virtual方法的类,不必是abstract类
3:
abstract方法只不过是virtual方法的纯粹版本,abstract方法也有virtual方法的动态机制(即运行时根据对象引用的具体类型调用相应的方法,也可以说当前引用中调用派生层次最深的方法).
4.
重写两种方法,必须在派生类中用override声明.如果不使用override的话
对于abstract方法:
编译器会报错,因为没有实现抽象类的方法.
对于virtual方法:
相当于覆盖了virtual方法,使用一个参数列表和返回值,函数名一样的方法. 该方法不再作为virtual方法,而是普通函数.虚函数搜索时将不再搜索该函数.
此时编译器会给出警告.因为你用一个函数原型几乎一模一样的方法覆盖了虚方法.如果确实需要这样做,在方法前加new关键字,显示表明要覆盖虚方法.
编译器不再给出警告.
综上.abstract方法,virual方法与C++中纯虚函数,虚函数的概念是一致的.
C++中
1.
纯虚函数必须没有实现
声明了纯虚函数的类一定是抽象基类(ABC)(自动成为,不必额外声明)
2.
而不是纯的虚函数,则必然有实现,否则就成了纯虚函数(除非进行方法声明,又不给出定义,并且没有 在声明后面指出这是纯虚函数,即"= 0", 这种情况下,任何调用该方法的语句都会导致链接错误,相当于无用函数)
有虚函数的类,当然可以不必是抽象基类.
3.
纯虚函数和虚函数当然都有同样的动态机制.
所以,结论是:
C#中abstract方法,virual方法与C++中纯虚函数,虚函数的概念是一致的.
测试代码:
abstract public class animal
{
public abstract string get();
public virtual string eat() { return "animal"; }
}
abstract public class waterAnimal : animal
{
//public override string get()
//{
// return ToString();
//}
public override string eat() { return "wateranimal"; }
}
public class fish : waterAnimal
{
public override string get()
{
return ToString();
}
new public string eat() { return "fish"; }
}
public class landAnimal:animal
{
public override string get()
{
return this.ToString();
}
public string get(int a)
{
return "notOverride";
}
}
public class cat:landAnimal
{
public override string get()
{
return this.ToString();
}
}
public class dog : landAnimal
{
public override string get()
{
return this.ToString();
}
}
class Program
{
static void Main(string[] args)
{
animal a = new fish();
Console.WriteLine(a.eat());
//waterAnimal w = new waterAnimal();
//Console.WriteLine(w.eat());
a = new cat();
landAnimal l = new cat();
Console.WriteLine(a.get());
Console.WriteLine(l.get());
a = new dog();
try
{
cat c = a as cat;
c = (cat)a;
}catch(Exception e)
{
Console.WriteLine(e.Message);
}
}
}
哪里说错,请纠正.
摘自 zbwzll2的专栏
补充:软件开发 , C# ,