|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
不可能天天有学习.net),我一同学说,你应该早就有作品啦。我惶惶然……系列文章目次索引:《你必需晓得的.NET》
<br>说在,开篇之前在.NET天下里,我们经常听到的一句话莫过于“System.Object是统统范例的根,是一切范例的父类”,以致于我在《你必需晓得的.NET》8.1节以“万物回宗:System.Object”如许的title为System.Object授与至高声誉。以是,基于如许的概念就有了上面这句“接口是不是也承继于System.Object?”,现实上这恰是明天在手艺群里小小会商的一个插曲。
anytao.com
1缘起
在.NET天下里,我们经常听到的一句话莫过于“System.Object是统统范例的根,是一切范例的父类”,以致于我在《你必需晓得的.NET》8.1节以“万物回宗:System.Object”如许的title为System.Object授与至高声誉。以是,基于如许的概念就有了上面这句“接口是不是也承继于System.Object?”,现实上这恰是明天在手艺群里小小会商的一个插曲。
持“interface也承继于object”,是基于以下的两个概念揣度的:
概念一:
接口实质上也是一个class,由于接口范例编译以后在IL中被标识为.class,既然是类那末不成制止的终极承继于System.Object。
概念二:
假设有以下的接口和完成接口的范例:- //Release:code01,2009/03/04//Author:Anytao,http://www.anytao.com//List:IObjectable.cspublicinterfaceIObjectable{}
复制代码- //Release:code02,2009/03/04//Author:Anytao,http://www.anytao.com//List:MyObject.cspublicclassMyObject:IObjectable{}
复制代码- 那末,关于IObjectable对象而言,上面的挪用是可行的:
复制代码- //Release:code03,2009/03/04//Author:Anytao,http://www.anytao.com//List:Program.csclassProgram{staticvoidMain(string[]args){IObjectableobj=newMyObject();//CallObjectinstancemethodsobj.ToString();//CallObjectstaticmethodsIObjectable.Equals(null,null);}}
复制代码 明显,IObjectable范例变量obj能够会见存在于System.Object中的实例办法ToString()和虚办法Equals,固然其他的几个大众服务也不破例:GetType()、Equals()、GetHashcode()、ReferenceEquals(),也能够由此揣度interface可会见Object办法的千丝万缕。
不成否定,以上概念的部分推理是完整准确的,可是却遗憾的招致了毛病的谜底,以是在本文中我将明白的找出:interface不承继于object的缘故原由和道理。关于接口实质话题的深度会商,请参考《你必需晓得的.NET》1.5“玩转接口”和7.4“面向笼统编程:接口和笼统类”的具体剖析。
2从面向对象寻觅谜底
为了找出接口承继的缘故原由,我想从接口存在的意义动手是最可以申明成绩的举措?接口,就像面向对象计划中的精灵,为OO头脑注进了魂灵和活气,接口冲破了承继在纵向上的扩大偏向,在横向赐与对象以更天真的撑持机制。
接口,封装了关于举动的笼统,界说了完成者必需恪守的左券。比方,完成了System.ICloneable接口的范例被付与了“能够被拷贝”如许的左券,完成了System.Collections.IEnumerable接口的范例被付与了“能够被列举”如许的左券,分歧的接口界说了分歧的左券,就像分歧的功令束缚了分歧的举动。那末接口应当付与的左券最少在条理上坚持绝对的纯真和一致,假如为一切接口都无一破例的付与GetType()、Equals()、GetHashcode()、ReferenceEquals()另有ToString()如许的左券,不免使得接口的纯正和一致变得无从谈起,比方强制任何完成了System.ICloneable接口的范例同时恪守其他的商定是对ICloneable自己的凌辱。
从接口单一准绳延长思索,一个包括杂七杂八的接口界说明显不是interface应当具有的纯粹血缘,关于深谙面向对象为什么物的.NET计划者而言,这是不问可知的成绩。以是,我们从接口自己的职责和意义动身,决意interface不从System.Object承继是完整准确的。
3在IL寻找事实
再次使用壮大的IL兵器来寻找现实的原形,我们以Reflector翻开一切的.NET既有接口,比方IList、IEmumerable、ICollection,城市有个配合的发明那就是你找不到extendsSystem.Object如许的标识:- .classpublicinterfaceabstractautoansiICloneable{.custominstancevoidSystem.Runtime.InteropServices.ComVisibleAttribute::.ctor(bool)={bool(true)}.methodpublichidebysignewslotabstractvirtualinstanceobjectClone()cilmanaged{}}
复制代码- 自界说范例也是云云,我们看看IObjectable的IL反编译界说:
复制代码- .classpublicinterfaceabstractautoansiIObjectable{}
复制代码- 而以extends标识承继干系是IL代码告知我们原形的最好证实。
复制代码 System.Object真是“万物回宗”吗?
让我们再次回眸一笑,把Object举行一番把玩,岂非统统范例都得承继自Object吗?实在否则。以ILASM.exe举行IL代码编译时,有一个参数选项NOAUTOINHERIT,正如其注释所形貌的那样:- /NOAUTOINHERITDisableinheritingfromSystem.Objectbydefault
复制代码 明显NoAutoInherit选项供应了为.NET范例“往失落帽子”的感化,复杂言之就是,在未指定基类时,克制范例主动从Object承继。
我们能够玩儿一个翻来覆往的IL游戏,将我们本文入手下手的Anytao.Insidenet.InterfaceInside.exe把持台程序以ILDASM.exe工具Dump为IL代码My.il,比方MyObject被反编译为:- .classpublicautoansibeforefieldinitAnytao.Insidenet.InterfaceInside.MyObjectextends[mscorlib]System.ObjectimplementsAnytao.Insidenet.InterfaceInside.IObjectable{.methodpublichidebysigspecialnamertspecialnameinstancevoid.ctor()cilmanaged{//Codesize7(0x7).maxstack8IL_0000:ldarg.0IL_0001:callinstancevoid[mscorlib]System.Object::.ctor()IL_0006:ret}//endofmethodMyObject::.ctor}//endofclassAnytao.Insidenet.InterfaceInside.MyObject
复制代码 我们能够选择删除个中一切extends承继的代码,再以ILASM.exe对其举行noautoinherit编译,并天生- //Release:code02,2009/03/04//Author:Anytao,http://www.anytao.com//List:MyObject.cspublicclassMyObject:IObjectable{}0
复制代码 重生成的noobject.exe程序将没有从object承继,某种水平上冲破了“万物回宗”的创奇,MyObject就像一个无根之木,飘飖在我呆板的某个深处。
4结论
interface不从object承继,那末足下卓识呢?文章虽短,取一瓢饮之,畅也。
那末,我们该怎样回覆本文入手下手对此质疑的两种概念呢?
回覆概念一:
接口实质上仍是一个类,可是一个特别的类,它的特别性体现在诸多的方面,比方一切的办法和属性都是笼统的、撑持多承继等等,既然特别那就特别究竟,不承继于任何的父类也是个中之一吧。
固然这类注释不免牵强,可是如前文所述回到接口根源的角度而言,倒是最好的注释。
回覆概念二:
.NET统统范例都隐式承继于System.Object,那末关于完成了任何接口的范例而言,比方:- //Release:code02,2009/03/04//Author:Anytao,http://www.anytao.com//List:MyObject.cspublicclassMyObject:IObjectable{}
复制代码 其在实质上相称于:- //Release:code02,2009/03/04//Author:Anytao,http://www.anytao.com//List:MyObject.cspublicclassMyObject:IObjectable{}2
复制代码 以是关于MyObject实例obj而言,obj.ToString()本色是MyObject类承继于object,而不代表接口IObjectable也承继于object。那末IObjectable.Equals()则是编译器做了四肢举动,将IObjectable.Equals()翻译为Object.Equals()而至。现实上,关于接口声明范例的办法挪用,在完成机制上完整分歧于一样平常的间接办法挪用和虚办法分拨机制,我们将在后续篇幅中具体会商这一更主要的话题。
好了,interface,想说爱你不简单,大概我们还会再次相遇,也敬请伴侣们持续存眷:你必需晓得的.NET。
参考文献
- 《你必需晓得的.NET》1.5“玩转接口”
- 《你必需晓得的.NET》7.4“面向笼统编程:接口和笼统类”
- http://www.ckuyun.com/allenlooplee/archive/2007/01/22/627386.html
来自:http://www.ckuyun.com/anytao/archive/2009/03/05/must_net_27.html
完全不一样的。.net其实我也说不太清,.net可以把他理解为跟J2EE相对的工具。c++主要做系统相关的开发你要学.net的话就应该学C#。(其实微软在.NET平台上也考虑了给C++留一个地位。 |
|