在C#中,如果一个类的某个方法加了vitual的描述符,那么表示你可以在这个类的子类中重新实现该方法。Java中没有这么多废话,一个public或者protected方法不需要添加其它的描述符就可以在子类中被覆盖。
如果我们去掉Father类中GetNumber()方法的vitual描述符,那么在编译程序的时候会报错:
错误
1
“ConsoleApplication5.Children.GetNumber()”: 继承成员“ConsoleApplication5.Father.GetNumber()”未被标记为
virtual
、
abstract
或
override
,无法进行重写 D:我的文档Visual Studio
2005
ProjectsWindowsApplication1ConsoleApplication5Program.cs
23
29
ConsoleApplication5
这说明,如果在C#程序中,如果不在父类的方法中添加virtual、abstract或者override描述符,那么编译器就会认为你不想在子类中覆盖这个方法。如果我们同时去掉Children类中GetNumber()方法的override描述符,程序可以编译通过,但是这时就不是覆盖了,而是C#中的“隐藏”关系。“隐藏”和“覆盖”具体区别就是,如果是“隐藏”,那么在通过Father类型的引用调用一个Children对象的GetNumber()方法的时候,实际执行的部分是父类中的GetNumber()方法,而不是子类的。
因此,可以简单的这么理解,“覆盖”就是重新实现了父类的方法,而“隐藏”只是把父类中的方法藏了起来,通过父类的引用来调用这个方法的时候,这个被“隐藏”的方法就被激活了。
class
Program
{
static void Main(string[] args) {
Children c = new Children();
Console.WriteLine(c.GetNumber());
Console.WriteLine(((Father)c).GetNumber());
}
}

class
Father
{
public int GetNumber() {
return 1;
}
}

class
Children : Father
{
public int GetNumber() {
return 2;
}
}
结果:
2
1
class
Program {
static void Main( string [] args) {
Children c = new Children();
Console.WriteLine(c.GetNumber());
Console.WriteLine(((Father)c).GetNumber());
}
}
class Father {
public virtual int GetNumber() {
return 1 ;
}
}
class Children : Father {
public override int GetNumber() {
return 2 ;
}
}
结果:
2
2
static void Main( string [] args) {
Children c = new Children();
Console.WriteLine(c.GetNumber());
Console.WriteLine(((Father)c).GetNumber());
}
}
class Father {
public virtual int GetNumber() {
return 1 ;
}
}
class Children : Father {
public override int GetNumber() {
return 2 ;
}
}
结果:
2
2


因此,可以简单的这么理解,“覆盖”就是重新实现了父类的方法,而“隐藏”只是把父类中的方法藏了起来,通过父类的引用来调用这个方法的时候,这个被“隐藏”的方法就被激活了。



















结果:
2
1