C#中继承与函数覆盖,有时比较复杂,不小心很容易弄错。所以有必要总结点规律出来。
(1)
当子类中拥有和父类一样的可见field和member function时,子类中的field和member function会覆盖父类中的定义。
using System;
namespace TestInheritance
{
public class Bird
{
public string type = "Bird";
public void ShowType()
{
Console.WriteLine("Type is {0}", type);
}
}
public class Chicken : Bird
{
//同名的field,可见性为public或者protected,不管有没有声明为new,均会覆盖父类中的field
public new string type = "Chicken";
//当子类含有和父类相同的函数签名(可见性public或者protected、函数名和参数都相同)时,不管带new与否,都将覆盖父类中相同的函数
public /**//*new*/ void ShowType()
{ Console.WriteLine();
Console.WriteLine("This is Chicken::ShowType()", type);
}
}
public class TestInheritance
{
public static void Main()
{
Bird bird = new Chicken();
bird.ShowType();
Console.WriteLine();
Chicken chicken = new Chicken();
chicken.ShowType();
Console.WriteLine();
Console.WriteLine("Type is {0}", chicken.type);
Console.Read();
}
}
}
如上例中的输出会是:
Type is Bird
This is Chicken::ShowType()
Type is Chicken
(2) 当子类中的member function 和field作用范围比父类中对应的member function和field小时,只会对作用范围内的部分产生覆盖影响,对作用范围外无影响。
如下例:
using System;
namespace TestInheritance
{
public class Bird
{
public string type = "Bird";
public void ShowType()
{
Console.WriteLine("Type is {0}", type);
}
}
public class Chicken : Bird
{
//这里的type只会对Chicken内部的函数有影响,出了Chicken类,该函数不具有作用。
private new string type = "Chicken";
//这里的ShowType()函数只会对Chicken内部的函数有影响,出了Chicken类,该函数不具有作用。
private /**//*new*/ void ShowType()
{
Console.WriteLine("This is Chicken::ShowType()", type);
}
public void ShowInfo()
{
ShowType();
}
}
public class TestInheritance
{
public static void Main()
{
Bird bird = new Chicken();
bird.ShowType();
Console.WriteLine();
Chicken chicken = new Chicken();
chicken.ShowType();
Console.WriteLine();
Console.WriteLine("Type is {0}", chicken.type);
Console.WriteLine();
chicken.ShowInfo();
Console.Read();
}
}
}
输出:
Type is Bird
This is Bird
Type is Bird
This is Chicken::ShowType()
又如下例:
using System;
namespace TestInheritance
{
public class Bird
{
public string type = "Bird";
public void ShowType()
{
Console.WriteLine("Type is {0}", type);
}
}
public class Chicken : Bird
{
//这里的type只会对Chicken内部的函数有影响,出了Chicken类,该函数不具有作用。
protected new string type = "Chicken";
//这里的ShowType()函数只会对Chicken内部的函数有影响,出了Chicken类,该函数不具有作用。
protected /**//*new*/ void ShowType()
{
Console.WriteLine("This is Chicken::ShowType()", type);
}
public void ShowInfo()
{
ShowType();
}
}
public class Cock : Chicken
{
public void ShowInfo()
{
Console.WriteLine("Cock::ShowInfo()");
//这里会调用Chicken的type成员
Console.WriteLine(type);
//这里将调用Chicken的ShowType()函数
ShowType();
}
}
public class TestInheritance
{
public static void Main()
{
Bird bird = new Chicken();
//调用Bird的ShowType()函数
bird.ShowType();
Console.WriteLine();
Chicken chicken = new Chicken();
//这里会调用Bird的ShowType();
chicken.ShowType();
//这里chicken.type会为Bird,因为Chicken类中type为protected,在这里没法访问
Console.WriteLine("Type is {0}", chicken.type);
chicken.ShowInfo();
Console.WriteLine();
Cock cock = new Cock();
cock.ShowInfo();
Console.Read();
}
}
}
会输出:
Type is Bird
Type is Bird
Type is Bird
This is Chicken::ShowType()
Cock::ShowInfo()
Chicken
This is Chicken::ShowType()
(3) 当子类中的member function 和父类的member function名字相同但参数不同时,不会产生覆盖。如:
using System;
namespace TestInheritance
{
public class Bird
{
public string type = "Bird";
public void ShowType()
{
Console.WriteLine("Type is {0}", type);
}
}
public class Chicken : Bird
{
//这里的type只会对Chicken内部的函数有影响,出了Chicken类,该函数不具有作用。
protected new string type = "Chicken";
//不会覆盖Bird的ShowType函数,因为函数签名不同(参数不同)
public /**//*new*/ void ShowType(int x)
{
Console.WriteLine("int {0}",x);
Console.WriteLine("This is Chicken::ShowType()", type);
}
public void ShowInfo()
{
//会调用Bird的ShowType函数
Console.WriteLine();
Console.WriteLine("Chicken::ShowInfo()");
ShowType();
}
}
public class Cock : Chicken
{
public void ShowInfo()
{
Console.WriteLine();
Console.WriteLine("Cock::ShowInfo()");
//这里会调用Chicken的type成员
Console.WriteLine(type);
//这里将调用Bird的ShowType()函数
ShowType();
}
}
public class TestInheritance
{
public static void Main()
{
Bird bird = new Chicken();
//调用Bird的ShowType()函数
bird.ShowType();
Chicken chicken = new Chicken();
//这里会调用Bird的ShowType();
chicken.ShowType();
//这里chicken.type会为Bird,因为Chicken类中type为protected,在这里没法访问
Console.WriteLine("Type is {0}", chicken.type);
chicken.ShowInfo();
Cock cock = new Cock();
cock.ShowInfo();
Console.Read();
}
}
}
输出为:
Type is Bird
This is Bird
Type is Bird
Chicken::ShowInfo()
Type is Bird
Cock::ShowInfo()
Chicken
Type is Bird。
这里没有列举虚函数和override,考虑到篇幅,那个将在其它文章中予以说明,相信通过以上几个实例,大家可以对函数覆盖有个比较好的了解。