【问题标题】:Inheritance from multiple interfaces with the same method name从具有相同方法名称的多个接口继承
【发布时间】:2011-01-23 04:36:56
【问题描述】:

如果我们有一个继承自多个接口的类,并且这些接口有同名的方法,我们如何在我的类中实现这些方法?如何指定实现哪个接口的哪个方法?

【问题讨论】:

    标签: c# inheritance methods interface multiple-inheritance


    【解决方案1】:

    通过显式实现接口,如下所示:

    public interface ITest {
        void Test();
    }
    public interface ITest2 {
        void Test();
    }
    public class Dual : ITest, ITest2
    {
        void ITest.Test() {
            Console.WriteLine("ITest.Test");
        }
        void ITest2.Test() {
            Console.WriteLine("ITest2.Test");
        }
    }
    

    当使用显式接口实现时,函数在类上不是公共的。因此,为了访问这些函数,您必须首先将对象转换为接口类型,或者将其分配给声明为接口类型的变量。

    var dual = new Dual();
    // Call the ITest.Test() function by first assigning to an explicitly typed variable
    ITest test = dual;
    test.Test();
    // Call the ITest2.Test() function by using a type cast.
    ((ITest2)dual).Test();
    

    【讨论】:

    • 如果 Test() 在接口和 Dual 类中都声明为 public 怎么办?
    • 接口上的方法/属性总是公开的——这就是接口的全部意义。但是,当您使用显式接口实现 时,该函数在类上始终是私有的。这就是为什么您需要将类转换为您需要的特定接口的技术。当您确实实现了两个定义具有相同签名的方法的接口时,您无法避免这种情况。
    • 请注意另一个微妙的“特性”是每个方法可以有不同的返回类型,即使它们具有相同的方法签名。如果您不对所有或所有方法使用显式接口声明,但其中一种方法,通常不允许这样做。
    • @R.S.K 如果在 Dual 类中声明了 Test(),则两个接口都将使用它作为实现。您将无法同时拥有其他 两个 显式实现。
    【解决方案2】:

    【讨论】:

      【解决方案3】:

      您可以实现这些接口中的一个或两个explicitly

      假设你有这些接口:

      public interface IFoo1
      {
          void DoStuff();
      }
      
      public interface IFoo2
      {
          void DoStuff();
      }
      

      您可以像这样实现两者:

      public class Foo : IFoo1, IFoo2
      {
          void IFoo1.DoStuff() { }
      
          void IFoo2.DoStuff() { }        
      }
      

      【讨论】:

        【解决方案4】:

        您可以实现一个显式接口另一个隐式

        public interface ITest {
            void Test();
        }
        public interface ITest2 {
            void Test();
        }
        public class Dual : ITest, ITest2
        {
            public void Test() {
                Console.WriteLine("ITest.Test");
            }
            void ITest2.Test() {
                Console.WriteLine("ITest2.Test");
            }
        }
        

        ITest.Test 将是默认实现。

        Dual dual = new Dual();
        dual.Test();
        ((ITest2)dual).Test();
        

        输出:

        Console.WriteLine("ITest.Test");
        Console.WriteLine("ITest2.Test");
        

        【讨论】:

          【解决方案5】:

          有时您甚至可能需要这样做:

          public class Foo : IFoo1, IFoo2
          {
              public void IFoo1.DoStuff() { }
          
              public void IFoo2.DoStuff()
              {
                  ((IFoo1)this).DoStuff();
              }        
          }
          

          【讨论】:

          • 与创建一个正确接口类型的临时文件?不用了,谢谢。 readonly IFoo1 this1 = this; this1.DoStuff();
          • 在显式接口实现中包含代码的可继承类通常会给派生类带来麻烦。我建议作为一种替代模式,它有一个 protected 方法,其中包含两个接口成员的代码,并且两个接口成员都链接到该方法。将this 转换为接口类型以使用其成员通常是一种明显的代码异味。最好有一个protected 方法来实现相关成员并链接到该成员。
          【解决方案6】:
          public class ImplementingClass : AClass1, IClass1, IClass2
          
              {
                  public override string Method()
                  {
                      return "AClass1";
                  }
                  string IClass1.Method()
                  {
                      return "IClass1";
                  }
                   string IClass2.Method()
                  {
                      return "IClass2";
                  }
              }
          

          因此,当从不同的类调用时,您必须将对象类型转换为所需的接口或抽象类。

          ImplementingClass implementingClass = new ImplementingClass();
          ((AClass1)implementingClass).Method();
          

          【讨论】:

            【解决方案7】:
            public interface IDemo1
            {
             void Test();
            }
            public interface IDemo2
            {
             void Test();
            }
            public class clsDerived:IDemo1,IDemo2
            {
              void IDemo1.Test() 
              {
               Console.WriteLine("IDemo1 Test is fine");
              }
             void IDemo2.Test() 
              {
                Console.WriteLine("IDemo2 Test is fine");
              }
            }
            
            public void get_methodes()
            {
                IDemo1 obj1 = new clsDerived();
                IDemo2 obj2 = new clsDerived();
                obj1.Test();//Methode of 1st Interface
                obj2.Test();//Methode of 2st Interface
            }
            

            【讨论】:

              【解决方案8】:

              答案是“By using explicit Interface implementation

              举个例子:

              using System;
              
              interface A
              {
                  void Hello();
              }
              
              interface B
              {
                  void Hello();
              }
              
              class Test : A, B
              {
                  void A.Hello()
                  {
                      Console.WriteLine("Hello to all-A");
                  }
              
                  void B.Hello()
                  {
                      Console.WriteLine("Hello to all-B");
                  }
              }
              
              public class interfacetest
              {
                  public static void Main()
                  {
                      A Obj1 = new Test();
                      Obj1.Hello();
                      B Obj2 = new Test();
                      Obj2.Hello();
                  }
              }
              

              输出:

              Hello to all-A
              Hello to all-B
              

              【讨论】:

                【解决方案9】:
                  Dual dual = new Dual();
                  (dual as ITest).Test();
                  (dual as ITest2).Test();
                

                您可以将其用于您的代码

                【讨论】:

                  猜你喜欢
                  • 2011-02-19
                  • 1970-01-01
                  • 1970-01-01
                  • 2015-03-20
                  • 2020-12-05
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多