c# 子类覆盖父类方法
{
public void send()
{
Console.writeline("A");
}
}
public class B:A
{
public new void send()
{
Console.writeline("B");
}
}
如果我现在用A的名字来引用B:
A a=(B)(new A());
这样伙运行a.send();执行的是A的方法,而不是我重写的B的方法,但我希望使用B的方法,应该怎么弄? 展开
# 对方法的重载必须要显式声明,这个与 C++ 和 JAVA 都不同。见下面的 C# 程序:
class Plane
{
public double TopSpeed()
{
return 300.0D;
}
}
class Jet : Plane
{
public double TopSpeed()
{
return 900.0D;
}
}
class Airport : IEntryPoint
{
public void Main()
{
Plane plane = new Jet();
Console.WriteLine("planes top speed: {0}", plane.TopSpeed());
}
}
上面的程序很简单,在编译时会有警告:警告:“Jet.TopSpeed()隐藏了继承的成员Plane.TopSpeed()。如果是有意隐藏,请使用关键字 new。"E:\VisualStudioProj\ChouyTest\LearningCSharpByExample\io\ReadFile.cs 92 17 LearningCSharpByExample
但结果却出乎意料地是:
planes top speed: 300
很显然,它并没有调用子类的 TopSpeed 方法。原因是在 C# 中,方法如果想要被重载,必须显式地声明为 virtual,也就是虚方法。而继承类如果要重写此方法时,也必须显式地声明为 override ,这样才能覆盖父类方法。C# 代码如下:
class Plane
{
public virtual double TopSpeed()
{
return 300.0D;
}
}
class Jet : Plane
{
public override double TopSpeed()
{
return 900.0D;
}
}
class Airport : IEntryPoint
{
public void Main()
{
Plane plane = new Jet();
Console.WriteLine("planes top speed: {0}", plane.TopSpeed());
}
}
以上程序的输出结果是:
planes top speed: 900
在 C# 中,如果一个方法允许子类覆盖,则必须要显式声明为 virtual 的(在 JAVA 中,默认是 virtual 的),并且在子类里必须显式声明为 override。这两个关键子哪个也不能省。顺便再说一下另外的三个关键字:sealed、abstract、new。
在继承 abstract 类的 abstract 方法时,也必须声明方法为 override,abstract 方法的特性与 JAVA 中的抽象类是一样的。sealed 关键字意思是密封的,相当于 JAVA 中的 final,在类上使用是不可再被继承,在方法上使用是不可再覆盖;但还有一个例外,就是对方法使用 new 关键字声明。代码如下:
abstract class Plane
{
public virtual double TopSpeed()
{
return 300.0D;
}
}
class Jet : Plane
{
public sealed override double TopSpeed()
{
return 900.0D;
}
}
class UFO : Jet
{
public new double TopSpeed()
{
return 13000.0D;
}
}
class Airport : IEntryPoint
{
public void EntryPoint()
{
UFO plane = new UFO();
Console.WriteLine("planes top speed: {0}", ((Plane) plane).TopSpeed());
Console.WriteLine("planes top speed: {0}", ((Jet) plane).TopSpeed());
Console.WriteLine("planes top speed: {0}", ((UFO) plane).TopSpeed());
}
}
注意,我是把 UFO 对象强转成某一对象然后调用其 TopSpeed 方法的,上面程序的输出结果是:
planes top speed: 900
planes top speed: 900
planes top speed: 13000
总之:C# 在这方面增加了方法定义的灵活性,给用户的更大的权利。但用不好会出现比较奇怪的结果。所以我觉得在定义方法时全部都加上 sealed 或是 virtual 关键字,这样避免继承的类出错.
{
public override void send()
{
Console.writeline("B");
}
}
{
public void send()
{
Console.writeline("B");
}
}