程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> C#中的“多重繼承”教程

C#中的“多重繼承”教程

編輯:關於C#
 

C#的對象系統是個單根系統,不支持類的多繼承,只支持多接口實現,這在 某種程度帶來了一些不便:我們在系統設計時經常會抽象出一些接口,並為接口 提供一個抽象類作為默認的實現,然後實際使用的類可以從抽象類派生。如果一 個類實現了多接口,那我們只能選擇一個抽象類作為祖先類,再將其他接口的實 現手工加到類中。這種情況在C#3.0中有了變化,我們現在可以利用C#3.0的擴展方法來實現一 個“受限的多繼承”。

C#3.0中引入了擴展方法,可以利用一個靜態類的靜態方法為一個類或者接口 添加方法,關鍵是添加的方法是包含實現的,由此我們可以在C#3.0中為接口提 供一個帶實現的方法聲明,而無需額外的實現類!如果一個類實現了多個這樣的 接口,就可以達到類似多繼承的效果。

讓我們用代碼測試一下:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace Test35

{

   public interface ITestA{ }

   public static class ITestAHelper

   {

     public static void TestA(this ITestA obj)

     {

       Console.WriteLine("ITestAHelper.TestA");

     }

   }

   public interface ITestB{ }

   public static class ITestBHelper

   {

     public static void TestB(this ITestB obj)

     {

       Console.WriteLine("ITestBHelper.TestB");

     }

   }

   public class Test : ITestA, ITestB

   {

   }

   class Program

   {

     static void Main(string[] args)

     {

       Test obj1 = new Test();

       obj1.TestA();

       obj1.TestB();

       Console.ReadKey();

     }

   }

}

 

執行的結果:

ITestAHelper.TestA

ITestBHelper.TestB

 

ok!再多試一下,看看如果實現類中定義相同的方法會怎麼樣:

 

public interface ITestA { }

   public static class ITestAHelper

   {

     public static void TestA(this ITestA obj)

     {

       Console.WriteLine("ITestAHelper.TestA");

     }

   }

   public interface ITestB { }

   public static class ITestBHelper

   {

     public static void TestB(this ITestB obj)

     {

       Console.WriteLine("ITestBHelper.TestB");

     }

   }

   public class Test : ITestA, ITestB

   {

     //此方法與ITestA的TestA()擴展方法相同

     public void TestA()

     {

       Console.WriteLine("Test.TestA");

     }

   }

   class Program

   {

     static void Main(string[] args)

     {

       Test obj1 = new Test();

       //下面分別測試2種TestA()調用方式

        obj1.TestA();

       ((ITestA)obj1).TestA();

       Console.ReadKey();

     }

   }

 

執行的結果:

Test.TestA

ITestAHelper.TestA 

 

從這次的結果看,這裡有一點點問題,如果實現類有相同的方法,接口的擴 展方法總是被接口的實現類隱藏,那麼如何多態?加上virtual試試看,似乎 static方法是不能使用virtual修飾符的:

public static virtual void TestA(this ITestA obj)

     {

       Console.WriteLine("ITestAHelper.TestA");

     }

 

編譯出錯,看來此路不通。

再多試一下,如果接口中也定義相同的方法會這麼樣?

public interface ITestA

   {

     void TestA();

   }

   public static class ITestAHelper

   {

     public static void TestA(this ITestA obj)

     {

       Console.WriteLine("ITestAHelper.TestA");

     }

   }

 

執行的結果:

Test.TestA

Test.TestA

 

看來這樣的話,擴展方法似乎總是被藏在接口的實現方法後面了,我沒想出 在接口變量中有什麼方法可以訪問到它。或許Reflection可以?我沒有嘗試下去 。

接口和類的方法聲明可以和擴展方法相同,那一個類能不能實現2個擁有相同 的擴展方法的接口呢?測試結果是編譯錯誤,代碼比較簡單,有興趣的朋友可以 自己試試看。

在此做個小小的總結,利用C#3.0的擴展方法,我們可以為接口提供默認的實 現而無需定義一個實現類,如果一個類實現了多個這樣的接口,就可以達到類似 “多重繼承”的效果。但是這種方法也有局限性,因為static方法不能使用 virtual修飾符,所以接口的擴展方法只能被接口的實現類隱藏,而不能重寫, 無法實現多態的效果,這是個比較大的缺點。這點如果能解決,就完美了。沒辦 法,這個世界沒有完美的東西啊。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved