子非鱼,安知鱼之乐?

我的程序人生,累并快乐着。
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

C#学习笔记系列之一:new和override的区别

Posted on 2006-09-03 13:32  Jason Cui  阅读(975)  评论(1编辑  收藏  举报

近日为了工作需要,开始真正学习C#了,看了一遍教材《C#编程语言详解》,作者Anders Hejlsberg亲自编写,语言并不华丽,却如编译器一般的严谨和逻辑。

看完之后有一些想不太明白的地方,一个个攻破。

第一个问题就是,没有别的语言那些明显的标记符,比如VB里面的Function, Dim之类的。在C#里不管是变量还是属性,或者函数,都使用相同的声明过程:public int SomeThing,如果后面加上小括号,那么就是一个函数。否则,如果带有大括号,那么就是属性,再否则,就是变量了。

而没有这些修饰符之后,带来了另一个问题,如果完成类的多态性。这个概念是类里面最重要也最难理解的一个概念,找来找去,书上似乎没有明确的提到这个语法。不过发现了几个重要的词,virtual, override, new。前两个在看C++的时候已经见过了,这个new又是什么呢?根据书上的说法和VS的提示,好像跟override有些想像。但是肯定是有区别的,于是写段代码研究一下。

使用经典的Human类作为基类,实现一个函数Walk,两个子类Man和Woman,继承这个类,分别实现这个函数Walk,不带任何其它的开关符。Main函数里使用

Human h1=new Man();
h1.Walk();
Human h2
=new Woman();
h2.Walk();

来查看结果。如果基类里面的函数没有virtual修饰符,而且子类里面的函数也不带修饰符,那么编译器会报错,提示加上new。OK,加上去,结果两个函数显示的都是执行了基类的Walk。这个似乎不太符合多态的定义。

于是在基类的函数上加上virtual,给两个子类分别用override和new定义函数,再执行一遍。第一个过程调用了Man的Walk,这个是正确的多态过程。第二个过程调用的还是Human的Walk。

由此可以看出,new是给子类新增加了一个函数,可以说除了函数名字相同以外,它跟基类里面的这个同名函数没有任何关系。当使用子类的类型来调用的时候,它会运行子类中的函数,而如果类型是基类的话,被隐藏的基类函数就会站到前台来。只有使用virtual定义基类中的函数,并使用override标记子类中的函数,才可以达到想要的多态类。