乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      C#接口與抽象類學(xué)習(xí)筆記

       新進(jìn)小設(shè)計(jì) 2021-04-18

          本筆記摘抄自:https://www.cnblogs.com/solan/archive/2012/08/01/CSharp06.html,記錄一下學(xué)習(xí)過程以備后續(xù)查用。

          摘要:

          抽象類:是一種特殊的類,可以定義具有實(shí)現(xiàn)的方法,也可以定義未實(shí)現(xiàn)的方法契約,本身不能被實(shí)例化,只能在派生類中進(jìn)行實(shí)例化。接口:對(duì)一

      組方法簽名進(jìn)行統(tǒng)一的命名,只能定義未實(shí)現(xiàn)的方法契約,本身也不能被實(shí)例化,只能在實(shí)現(xiàn)類中進(jìn)行實(shí)例化。

          二者都可以有部分?jǐn)?shù)據(jù)成員(如:屬性),它們貌似有著相同的“契約”功能,但對(duì)各自的派生類(實(shí)現(xiàn)類)又有著不同的要求,那么,到底它們有何

      異同呢?下面將從四個(gè)方面來講解它們的相同與不同之處。

          一、定義

          抽象類 不能實(shí)例化。抽象類的用途是提供多個(gè)派生類可共享的基類的公共定義,是對(duì)類進(jìn)行抽象,可以有實(shí)現(xiàn),也可以不實(shí)現(xiàn)。使用關(guān)鍵字abstract

      進(jìn)行定義。

          下面定義一個(gè)抽象類:

      public abstract class Code_06_03
      {
      }

          通過ISDASM來看一下生成的IL:

      .class abstract auto ansi nested public beforefieldinit Code_06_03
             extends [mscorlib]System.Object
      {
      } // end of class Code_06_03

          可以看以,抽象類實(shí)際上是繼承了System.Object類,并且編譯器為它生成了一個(gè)默認(rèn)的構(gòu)造函數(shù)。

          接口 它是對(duì)一組方法簽名進(jìn)行統(tǒng)一命名,是對(duì)一組行為規(guī)范的定義,使用關(guān)鍵字interface進(jìn)行定義。

          下面定義一個(gè)接口:

      public interface ICode_06_01
      {
      }

          通過ISDASM來看一下生成的IL:

      .class interface abstract auto ansi nested public ICode_06_01
      {
      } // end of class ICode_06_01

          可以看到,接口實(shí)際上是把它當(dāng)成抽象類來看待,但是沒有構(gòu)造函數(shù)。無論是抽象類擁有構(gòu)造函數(shù),還是接口不擁有構(gòu)造函數(shù),它們都是不能被實(shí)例

      化的。

          二、成員的區(qū)別

          抽象類 描述:

          1)可以定義抽象方法,抽象方法沒有具體實(shí)現(xiàn),僅僅是一個(gè)方法的契約,在子類中重寫該方法。抽象類可以重寫父類的虛方法為抽象方法。

          2)可以定義非抽象方法,但要求該方法要有具體實(shí)現(xiàn),如果該方法是虛方法,則在子類中可以重寫該方法。

          3)可以定義字段、屬性、抽象屬性、事件及靜態(tài)成員。

          下面是對(duì)類Code_06_03的擴(kuò)充:

          class Program
          {
              /// <summary>
              /// 抽象類
              /// </summary>
              public abstract class Code_06_03
              {
                  Dictionary<Guid, string> root = new Dictionary<Guid, string>();
                  public string Sex { get; set; }
                  public abstract string Address { get; }
                  public abstract int Add(int a, int b);
      
                  protected virtual string GetAddress(string addressID)
                  {
                      return addressID + " 廣東";
                  }
      
                  public void AddRoot(Guid id, string rootName)
                  {
                      root.Add(id, rootName);
                      OnAddRoot();
                  }
      
                  public event EventHandler AddRootEvent;
      
                  void OnAddRoot()
                  {
                      AddRootEvent?.Invoke(this, null);
                  }
      
                  public string this[Guid key]
                  {
                      get
                      {
                          return root[key];
                      }
                      set
                      {
                          root[key] = value;
                      }
                  }
              }
      
              static void Main(string[] args)
              {
      
              }
          }
      View Code

          2.1抽象方法public abstract int Add(int a, int b);的IL:

      .method public hidebysig newslot abstract virtual 
              instance int32  Add(int32 a,
                                  int32 b) cil managed
      {
      } // end of method Code_06_03::Add

          編譯器把Add方法當(dāng)作一個(gè)虛方法,在子類中可以被重寫。

          2.2虛方法protected virtual string GetAddress(string addressID)的IL:

      .method family hidebysig newslot virtual 
              instance string  GetAddress(string addressID) cil managed
      {
        // 略過
      } // end of method Code_06_03::GetAddress

          它本來就是一個(gè)虛方法,所以編譯器并沒有特殊對(duì)待它。

          2.3方法public void AddRoot(Guid id, string rootName)的IL:

      .method public hidebysig instance void  AddRoot(valuetype [mscorlib]System.Guid id,
                                                      string rootName) cil managed
      {
        // 略過
      } // end of method Code_06_03::AddRoot

          它也是一個(gè)普通的對(duì)象方法。

          接口 描述:

          1)可以定義屬性及索引器,但不能定義字段。

          2)可以定義事件。

          3)可以定義方法,僅僅是方法簽名的約定,不得有實(shí)現(xiàn),在實(shí)現(xiàn)類中對(duì)該方法進(jìn)行具體實(shí)現(xiàn),有點(diǎn)類似于抽象類的抽象方法。

          4)不可以定義虛方法。

          5)不可以定義任何靜態(tài)成員。

          6)接口成員默認(rèn)是全開放的,不得有訪問修飾符。

          下面是對(duì)類Code_06_01的擴(kuò)充:

          class Program
          {
              /// <summary>
              /// 接口
              /// </summary>
              public interface ICode_06_01
              {
                  string Name { get; set; }
                  int Add(int a, int b);
                  event EventHandler AddEvent;
              }
      
              static void Main(string[] args)
              {
      
              }
          }
      View Code

          2.4方法int Add(int a, int b);的IL:

      .method public hidebysig newslot abstract virtual 
              instance int32  Add(int32 a,
                                  int32 b) cil managed
      {
      } // end of method ICode_06_01::Add

          可以看到,定義的時(shí)候,我們并沒有為其指定可訪問修飾符(編譯器也不允許我們明文指定其可訪問修飾符),但編譯器默認(rèn)將它的訪問級(jí)

      別指定為public,另外是把它當(dāng)作一個(gè)抽象的虛方法。

          至于成員屬性和事件,編譯器則將它們當(dāng)作普通的對(duì)象屬性和對(duì)象事件對(duì)待,會(huì)為它們生成相應(yīng)的get/set和add/remove 方法,并無特別之

      處。

          三、實(shí)現(xiàn)方式的區(qū)別

          抽象類 實(shí)現(xiàn):

          由于抽象類也是類,所以對(duì)它的實(shí)現(xiàn)就像普通的繼承一樣,子類通過繼承可以得到抽象類的公有成員,且可以重寫部分成員,如虛方法和抽象

      方法等。

          下面是對(duì)Code_06_03類的實(shí)現(xiàn):

          class Program
          {
              /// <summary>
              /// 抽象類
              /// </summary>
              public abstract class Code_06_03
              {
                  Dictionary<Guid, string> root = new Dictionary<Guid, string>();
                  public string Sex { get; set; }
                  public abstract string Address { get; }
      
                  /// <summary>
                  /// 抽象方法ADD
                  /// </summary>
                  /// <param name="a"></param>
                  /// <param name="b"></param>
                  /// <returns></returns>
                  public abstract int Add(int a, int b);
      
                  /// <summary>
                  /// 虛方法GetAddress
                  /// </summary>
                  /// <param name="addressID"></param>
                  /// <returns></returns>
                  protected virtual string GetAddress(string addressID)
                  {
                      return addressID + " 廣東";
                  }
      
                  public void AddRoot(Guid id, string rootName)
                  {
                      root.Add(id, rootName);
                      OnAddRoot();
                  }
      
                  public event EventHandler AddRootEvent;
      
                  void OnAddRoot()
                  {
                      AddRootEvent?.Invoke(this, null);
                  }
      
                  public string this[Guid key]
                  {
                      get
                      {
                          return root[key];
                      }
                      set
                      {
                          root[key] = value;
                      }
                  }
              }
      
              /// <summary>
              /// 抽象類的實(shí)現(xiàn)
              /// </summary>
              public class Code_06_04 : Code_06_03
              {
                  public override int Add(int a, int b)
                  {
                      return a + b;
                  }
                  protected override string GetAddress(string addressID)
                  {
                      return "GuangDong";
                  }
      
                  readonly string addressPrefix = "China ";
                  public override string Address
                  {
                      get { return addressPrefix; }
                  }
              }
      
              static void Main(string[] args)
              {
      
              }
          }
      View Code

          通過ISDASM來看一下生成的IL:

          可以看到類Code_06_04是標(biāo)準(zhǔn)地對(duì)繼承類Code_06_03,兩個(gè)重寫的方法Add和GetAddress都是普通的對(duì)象方法,只是依然被

      當(dāng)作虛方法來看待。

          3.1方法Add的IL:

      .method public hidebysig virtual instance int32 
              Add(int32 a,
                  int32 b) cil managed
      {
        // 略過
      } // end of method Code_06_04::Add

          3.2方法GetAddress的IL:

      .method family hidebysig virtual instance string 
              GetAddress(string addressID) cil managed
      {
        // 略過
      } // end of method Code_06_04::GetAddress

          因?yàn)檫@兩個(gè)方法保持著虛方法的特性,所以對(duì)于Code_06_04類的子類,同樣還可以重寫這兩個(gè)方法。屬性成員Address這里還

      是一普通的對(duì)象屬性。

          接口 實(shí)現(xiàn)

          對(duì)接口的實(shí)現(xiàn)跟對(duì)抽象類的實(shí)現(xiàn)相似,下面是對(duì)接口ICode_06_01的實(shí)現(xiàn):

          class Program
          {
              /// <summary>
              /// 接口
              /// </summary>
              public interface ICode_06_01
              {
                  string Name { get; set; }
                  int Add(int a, int b);
                  event EventHandler AddEvent;
              }
      
              /// <summary>
              /// 接口的實(shí)現(xiàn)
              /// </summary>
              public class Code_06_02 : ICode_06_01
              {
                  public string Name { get; set; }
      
                  public int Add(int a, int b)
                  {
                      OnAdded();
                      return a + b;
                  }
      
                  public event EventHandler AddEvent;
      
                  void OnAdded()
                  {
                      AddEvent?.Invoke(this, null);
                  }
              }
      
              static void Main(string[] args)
              {
      
              }
          }
      View Code

          通過ISDASM來看一下生成的IL:

          它與普通類的區(qū)別不大,只是很明確的是實(shí)現(xiàn)了接口ICode_06_01,來看一下它的IL:

      .class auto ansi nested public beforefieldinit Code_06_02
             extends [mscorlib]System.Object
             implements LinkTo.Test.InterfaceAndAbstractClass.Program/ICode_06_01
      {
      } // end of class Code_06_02

          可以看到,類Code_06_02不僅繼承于System.Object類,同時(shí)還實(shí)現(xiàn)了接口ICode_06_01。再來看一下對(duì)于接口中的方法,編

      譯器是如何處理的?

          3.3方法Add的IL:

      .method public hidebysig newslot virtual final 
              instance int32  Add(int32 a,
                                  int32 b) cil managed
      {
        // 略過
      } // end of method Code_06_02::Add

          編譯器認(rèn)為Add方法具有虛方法的特性。而對(duì)于屬性和事件,依然是普通的實(shí)現(xiàn),如get/set、add/remove。另外,接口還支持

      顯示實(shí)現(xiàn)接口,我們上面討論的Code_06_02類對(duì)接口的實(shí)現(xiàn)默認(rèn)是隱式實(shí)現(xiàn)。

          在接口的實(shí)現(xiàn)類內(nèi)部,可以存在一個(gè)與接口某一方法名(包括簽名)完全相同的方法,但要求對(duì)接口實(shí)現(xiàn)的那個(gè)方法必須是顯

      示實(shí)現(xiàn),如下代碼:

              public int Add(int a, int b)
              {
                  return a + b;
              }
      
              int ICode_06_01.Add(int a, int b)
              {
                  OnAdded();
                  return a + b;
              }

          可以看出顯示實(shí)現(xiàn)就是在方法前加上接口名和點(diǎn)號(hào)(ICode_06_01.),另外方法是不能有可訪問修飾符的,編譯器會(huì)對(duì)其進(jìn)行

      private處理。那如何才能調(diào)用顯示實(shí)現(xiàn)的接口方法呢?可以將實(shí)現(xiàn)類的對(duì)象轉(zhuǎn)為一個(gè)接口變量,再調(diào)用該變量的相應(yīng)方法,如下

      代碼:

              static void Main(string[] args)
              {
                  Code_06_02 code0602 = new Code_06_02();
                  ICode_06_01 icode0602 = code0602;
                  var result = icode0602.Add(1, 2);
                  Console.WriteLine($"Result={result}");
                  Console.Read();
              }

          而對(duì)于抽象類的實(shí)現(xiàn),是不能進(jìn)行顯示實(shí)現(xiàn)的。

          四、應(yīng)用中的區(qū)別

          1)抽象類保留一普通類的部分特性,定義可能已經(jīng)實(shí)現(xiàn)的方法行為,方法內(nèi)可以對(duì)數(shù)據(jù)成員(如屬性)進(jìn)行操作,且方法可以

      相互溝通。而接口僅僅是定義方法的簽名,就像規(guī)則,只是約定,并沒有實(shí)現(xiàn)。

          2)抽象類的派生類可以原封不動(dòng)地得到抽象類的部分成員,接口的實(shí)現(xiàn)類如果想要得到接口的數(shù)據(jù)成員,則必須對(duì)其進(jìn)行重寫。

          3)一個(gè)類只能繼承于一個(gè)類(含抽象類),但可以實(shí)現(xiàn)多個(gè)接口,并且可以在繼承一個(gè)基類的基礎(chǔ)上,同時(shí)實(shí)現(xiàn)多個(gè)接口。

          4)抽象類和接口都不能對(duì)其使用密封sealed,事實(shí)上這兩者都是為了被其他類繼承和實(shí)現(xiàn),對(duì)其使用sealed是沒有任何意義的。

          5)抽象類可以對(duì)接口進(jìn)行實(shí)現(xiàn)。

          6)抽象類更多的用于“復(fù)制對(duì)象副本”,就是我們常說的“子類與父類有著is a的關(guān)系”,它更多關(guān)注于一個(gè)對(duì)象的整體特性。接口

      更多傾向于一系列的方法操作,這些操作在當(dāng)前上下文中既有著相同作用對(duì)象,又相互隔離。

          7)某些時(shí)候,抽象類可以與接口互換。

          通過生活中常見的紅娘搭線的示例:紅娘(Matchmaker)安排相親者(wooer)見面并指導(dǎo)場(chǎng)面話,來說明接口與抽象類給我們

      帶來的方便性。

          下面代碼演示不使用接口與抽象類的紅娘搭線:

          class Program
          {
              /// <summary>
              /// 紅娘類
              /// </summary>
              public class Matchmaker
              {
                  string message;
      
                  /// <summary>
                  /// 場(chǎng)面話、客套話指導(dǎo)
                  /// </summary>
                  public void Teach()
                  {
                      message = "曾經(jīng)有一份真摯的愛情擺在我面前……";
                      Wooer wooer = new Wooer();
                      wooer.Say(message);
                  }
              }
      
              /// <summary>
              /// 相親者類
              /// </summary>
              public class Wooer
              {
                  /// <summary>
                  /// 場(chǎng)面話、客套話大全
                  /// </summary>
                  /// <param name="message"></param>
                  public void Say(string message)
                  {
                      Console.WriteLine(message);
                  }
              }
      
              static void Main(string[] args)
              {
                  #region 不使用接口及抽象類的紅娘搭線
                  Matchmaker matchmaker = new Matchmaker();
                  matchmaker.Teach();
                  Console.Read();
                  #endregion
              }
          }
      View Code

          運(yùn)行結(jié)果如下:

          以上功能實(shí)現(xiàn)沒有問題,但是假如相親者想要增加一點(diǎn)肢體動(dòng)作或文藝展示來博取對(duì)方好感的話,紅娘就得跟著變。于是,紅娘

      搭建了一個(gè)相親平臺(tái)……

          下面代碼演示使用接口與抽象類的紅娘搭線:

          class Program
          {
              /// <summary>
              /// 紅娘類
              /// </summary>
              public class MatchmakerNew
              {
                  string message;
                  /// <summary>
                  /// 場(chǎng)面話、客套話指導(dǎo)
                  /// </summary>
                  public void Teach(IWooer wooer)
                  {
                      message = "曾經(jīng)有一份真摯的愛情擺在我面前……";
                      wooer.Say(message);
                  }
              }
              /// <summary>
              /// 相親者接口
              /// </summary>
              public interface IWooer
              {
                  /// <summary>
                  /// 房子車子票子……
                  /// </summary>
                  string Message { get; }
                  /// <summary>
                  /// 能歌善舞……
                  /// </summary>
                  void Action();
                  /// <summary>
                  /// 甜言蜜語……
                  /// </summary>
                  /// <param name="message"></param>
                  void Say(string message);
              }
      
              /// <summary>
              /// 男相親者實(shí)現(xiàn)類
              /// </summary>
              public class ManWooer : IWooer
              {
                  public string Message
                  {
                      get { return "嫁給我,房子車子票子啥都有。"; }
                  }
                  public void Action()
                  {
                      Console.WriteLine("野狼disco……");
                  }
                  public void Say(string message)
                  {
                      Action();
                      Console.WriteLine(message + Message);
                  }
              }
      
              /// <summary>
              /// 女相親者實(shí)現(xiàn)類
              /// </summary>
              public class WomanWooer : IWooer
              {
                  public string Message
                  {
                      get { return "娶了我,這頭牛和后面的這座山都是你的。"; }
                  }
                  public void Action()
                  {
                      Console.WriteLine("相見恨晚……");
                  }
                  public void Say(string message)
                  {
                      Action();
                      Console.WriteLine(message + Message);
                  }
              }
      
              static void Main(string[] args)
              {
                  #region 使用接口及抽象類的紅娘搭線
                  MatchmakerNew matchmakerNew = new MatchmakerNew();
      
                  //男大為婚
                  IWooer manWooer= new ManWooer();
                  matchmakerNew.Teach(manWooer);
                  manWooer.Say("親:");
                  Console.WriteLine();
      
                  //女大為嫁
                  IWooer womanWooer = new WomanWooer();
                  matchmakerNew.Teach(womanWooer);
                  womanWooer.Say("親:");
                  
                  Console.Read();
                  #endregion
              }
          }
      View Code

          運(yùn)行結(jié)果如下:

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多