<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      [你必須知道的.NET]第二十七回:interface到底繼承于object嗎?

      《你必須知道的.NET》網站 | Anytao技術博客 

      [你必須知道的.NET]第二十七回:interface到底繼承于object嗎?

      發布日期:2009.03.05 作者:Anytao
      ? 2009 Anytao.com ,Anytao原創作品,轉貼請注明作者和出處。

      說在,開篇之前
      在.NET世界里,我們常常聽到的一句話莫過于“System.Object是一切類型的根,是所有類型的父類”,以至于我在《你必須知道的.NET》8.1節 以“萬物歸宗:System.Object”這樣的title為System.Object授予至高榮譽。所以,基于這樣的觀點就有了下面這句“接口是否也繼承于System.Object?”,事實上這正是今天在技術群里小小討論的一個插曲。 

                                                                                            www.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.cs
      public interface IObjectable
      {
      }
      // Release : code02, 2009/03/04                    
      // Author  : Anytao, http://www.anytao.com
      // List    : MyObject.cs
      public class MyObject : IObjectable
      {
      }
      那么,對于IObjectable對象而言,下面的調用是可行的:
      // Release : code03, 2009/03/04                    
      // Author  : Anytao, http://www.anytao.com
      // List    : Program.cs
      class Program
      {
          static void Main(string[] args)
          {
              IObjectable obj = new MyObject();
      
              //Call Object instance methods
              obj.ToString();
              //Call Object static methods
              IObjectable.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,都會有個共同的發現那就是你找不到extends System.Object這樣的標識:

      .class public interface abstract auto ansi ICloneable
      {
          .custom instance void System.Runtime.InteropServices.ComVisibleAttribute::.ctor(bool) = { bool(true) }
          .method public hidebysig newslot abstract virtual instance object Clone() cil managed
          {
          }
      }
      自定義類型也是如此,我們看看IObjectable的IL反編譯定義:
      .class public interface abstract auto ansi IObjectable
      {
      }
      而以extends標識繼承關系是IL代碼告訴我們真相的最佳證明。

      System.Object真是“萬物歸宗”嗎?

      讓我們再次回眸一笑,把Object進行一番把玩,難道一切類型都得繼承自Object嗎?其實不然。以ILASM.exe進行IL代碼編譯時,有一個參數選項NOAUTOINHERIT,正如其解釋所描述的那樣:

      /NOAUTOINHERIT  Disable inheriting from System.Object by default

      顯然NoAutoInherit選項提供了為.NET類型“去掉帽子”的作用,簡單言之就是,在未指定基類時,禁止類型自動從Object繼承。

      我們可以玩兒一個翻來覆去的IL游戲,將我們本文開始的Anytao.Insidenet.InterfaceInside.exe控制臺程序以ILDASM.exe工具Dump為IL代碼My.il,例如MyObject被反編譯為:

      .class public auto ansi beforefieldinit Anytao.Insidenet.InterfaceInside.MyObject
             extends [mscorlib]System.Object
             implements Anytao.Insidenet.InterfaceInside.IObjectable
      {
        .method public hidebysig specialname rtspecialname 
                instance void  .ctor() cil managed
        {
          // Code size       7 (0x7)
          .maxstack  8
          IL_0000:  ldarg.0
          IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
          IL_0006:  ret
        } // end of method MyObject::.ctor
      
      } // end of class Anytao.Insidenet.InterfaceInside.MyObject

      我們可以選擇刪除其中所有extends繼承的代碼,再以ILASM.exe對其進行noautoinherit編譯,并生成

      ilasm /exe /output:noobject.exe /noautoinherit my.il

      新生成的noobject.exe程序將沒有從object繼承,某種程度上打破了“萬物歸宗”的創奇,MyObject就像一個無根之木,飄搖在我機器的某個深處。

      4 結論

      interface不從object繼承,那么足下高見呢?文章雖短,取一瓢飲之,暢也。

      那么,我們該如何回答本文開始對此質疑的兩種觀點呢?

      回答觀點一:

      接口本質上還是一個類,但是一個特殊的類,它的特殊性表現在諸多的方面,例如所有的方法和屬性都是抽象的、支持多繼承等等,既然特殊那就特殊到底,不繼承于任何的父類也是其中之一吧。

      雖然這種解釋未免牽強,但是如前文所述回到接口本源的角度而言,卻是最好的解釋。

      回答觀點二:

      .NET一切類型都隱式繼承于System.Object,那么對于實現了任何接口的類型而言,例如:

      // Release : code02, 2009/03/04                    
      // Author  : Anytao, http://www.anytao.com
      // List    : MyObject.cs
      public class MyObject : IObjectable
      {
      }

      其在本質上相當于:

      // Release : code02, 2009/03/04                    
      // Author  : Anytao, http://www.anytao.com
      // List    : MyObject.cs
      public class MyObject : Object, IObjectable
      {
      }

      所以對于MyObject實例obj而言,obj.ToString()實質是MyObject類繼承于object,而不代表接口IObjectable也繼承于object。那么IObjectable.Equals()則是編譯器做了手腳,將IObjectable.Equals()翻譯為Object.Equals()所致(來自腦袋高論,表示熱烈感謝)。事實上,對于接口聲明類型的方法調用,在實現機制上完全不同于一般的直接方法調用和虛方法分派機制,我們將在后續篇幅中詳細討論這一更重要的話題。

      好了,interface,想說愛你不容易,可能我們還會再次相遇,也敬請朋友們繼續關注:你必須知道的.NET

       

      補充討論:Leo ZhangInterface到底繼承于Object嗎?之我見

       

      友情支持:腦袋飛林沙博客園北京俱樂部


      anytao | ? 2009 Anytao.com

      2009/03/05 | http://anytao.cnblogs.com/ | http://www.rzrgm.cn/anytao/archive/2009/03/05/must_net_27.html

      本文以“現狀”提供且沒有任何擔保,同時也沒有授予任何權利。 | This posting is provided "AS IS" with no warranties, and confers no rights.

      本文版權歸作者所有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。

      參考文獻

      溫故知新

      [開篇有益]
      [第一回:恩怨情仇:is和as]
      [第二回:對抽象編程:接口和抽象類]
      [第三回:歷史糾葛:特性和屬性]
      [第四回:后來居上:class和struct]
      [第五回:深入淺出關鍵字---把new說透]
      [第六回:深入淺出關鍵字---base和this]
      [第七回:品味類型---從通用類型系統開始]
      [第八回:品味類型---值類型與引用類型(上)-內存有理]
      [第九回:品味類型---值類型與引用類型(中)-規則無邊]
      [第十回:品味類型---值類型與引用類型(下)-應用征途]
      [第十一回:參數之惑---傳遞的藝術(上)]
      [第十二回:參數之惑---傳遞的藝術(下)]
      [第十三回:從Hello, world開始認識IL]
      [第十四回:認識IL代碼---從開始到現在]
      [第十五回:繼承本質論]
      [第十六回:深入淺出關鍵字---using全接觸]
      [第十七回:貌合神離:覆寫和重載]
      [第十八回:對象創建始末(上)]
      [第十九回:對象創建始末(下)]
      [第二十回:學習方法論]
      [第二十一回:認識全面的null]
      [第二十二回:字符串駐留(上)---帶著問題思考]
      [第二十三回:品味細節,深入.NET的類型構造器]
      [第二十四回:認識元數據和IL(上)]
      [第二十五回:認識元數據和IL(中)]
      [第二十六回:認識元數據和IL(下)]

      posted @ 2009-03-05 02:08  Anytao  閱讀(10073)  評論(81)    收藏  舉報
      主站蜘蛛池模板: 精品国产三级a∨在线欧美| 亚洲精品成人无限看| A级日本乱理伦片免费入口| 久久亚洲精品情侣| 日韩无专区精品中文字幕| 国产精品99久久不卡| 亚洲精品中文字幕一二三| 色综合久久中文综合久久激情 | 亚洲欧美偷国产日韩| 欧美日韩国产va在线观看免费| 欧美日韩在线视频| 中文字幕亚洲精品第一页| 99在线 | 亚洲| 中文国产日韩欧美二视频| 成A人片亚洲日本久久| 国产精品一区二区三区91| 亚洲国产成人av国产自| 久久精品免视看国产成人| 999国产精品999久久久久久| 午夜夫妻试看120国产| 聊城市| 日韩精品无码去免费专区| 亚洲AV国产福利精品在现观看| 国产女人被狂躁到高潮小说| 国产精品一码在线播放| 黑人大荫道bbwbbb高潮潮喷| 日本久久99成人网站| 久久午夜私人影院| 中文字幕一区有码视三区| 国产精品激情av在线播放| 日韩人妻无码精品久久久不卡| 久久久久人妻一区精品色| 国产日韩av二区三区| 日本一区二区精品色超碰| 精品无人区一码二码三码| 国产精品 视频一区 二区三区| 国产成人一区二区三区免费| 91麻豆精品国产91久| 四虎影视一区二区精品| 国产成人精品aa毛片| 亚洲嫩模一区二区三区|