上周末两天,公司组织了 C# 的培训,培训公司找的微软的工程师当讲师给我们讲的。感觉讲得比较烂,讲师本人对 C# 的产品就不够熟悉,只知其然而不知其所以然。不说这个了,下面说说 C# 与 JAVA 不同的地方,而且比较有意思。
C# 对方法的重载必须要显式声明,这个与 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
但结果却出乎意料地是:
很显然,它并没有调用子类的 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()); } }
|
以上程序的输出结果是:
在 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 关键字,这样避免继承的类出错,再一个就是当有警告时一定要看看。
阅读(3629) | 评论(0) | 转发(0) |