Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1905493
  • 博文数量: 219
  • 博客积分: 8963
  • 博客等级: 中将
  • 技术积分: 2125
  • 用 户 组: 普通用户
  • 注册时间: 2005-10-19 12:48
个人简介

文章分类

全部博文(219)

文章存档

2021年(1)

2020年(3)

2015年(4)

2014年(5)

2012年(7)

2011年(37)

2010年(40)

2009年(22)

2008年(17)

2007年(48)

2006年(31)

2005年(4)

分类:

2009-02-23 15:50:22

 

上周末两天,公司组织了 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
但结果却出乎意料地是:

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 关键字,这样避免继承的类出错,再一个就是当有警告时一定要看看。

阅读(3521) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~