VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > Objective-C编程 >
  • c#3.0中的多重继承

制作者:剑锋冷月 单位:无忧统计网,www.51stat.net
 

  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修饰符,所以接口的扩展方法只能被接口的实现类隐藏,而不能重写,无法实现多态的效果,这是个比较大的缺点。这点如果能解决,就完美了。没办法,这个世界没有完美的东西啊。

 

 

  执行的结果:

  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修饰符,所以接口的扩展方法只能被接口的实现类隐藏,而不能重写,无法实现多态的效果,这是个比较大的缺点。这点如果能解决,就完美了。没办法,这个世界没有完美的东西啊。

 



相关教程