【问题标题】:inherit from two classes in C# [duplicate]从C#中的两个类继承[重复]
【发布时间】:2012-06-23 11:47:31
【问题描述】:

可能重复:
Multiple Inheritance in C#

我有两个类 Class A 和 Class B。这两个类不能互相继承。我正在创建名为 C 类的新类。现在,我想通过继承来实现 A 类和 B 类中的方法。我知道在 C# 中不可能进行多重继承,但有没有其他方法可以做到这一点?

【问题讨论】:

标签: c# .net


【解决方案1】:

多重继承在 C# 中是不可能的,但可以使用接口来模拟,请参阅Simulated Multiple Inheritance Pattern for C#。

基本思想是为类B上您希望访问的成员定义一个接口(称为IB),然后让C从A继承并在内部实现IB存储B的实例,例如:

class C : A, IB
{
    private B _b = new B();

    // IB members
    public void SomeMethod()
    {
        _b.SomeMethod();
    }
}

该页面还解释了其他几种替代模式。

【讨论】:

    【解决方案2】:

    继承的一个常见替代方法是委托(也称为组合):X“具有”Y 而不是 X“是”Y。 因此,如果 A 具有处理 Foos 的功能,而 B 具有处理 Bars 的功能,并且您希望两者都在 C 中,那么就像这样:

    public class A() {
      private FooManager fooManager = new FooManager(); // (or inject, if you have IoC)
    
      public void handleFoo(Foo foo) {
        fooManager.handleFoo(foo);
      }
    }
    
    public class B() {
      private BarManager barManager = new BarManager(); // (or inject, if you have IoC)
    
      public void handleBar(Bar bar) {
        barManager.handleBar(bar);
      }
    }
    
    public class C() {
      private FooManager fooManager = new FooManager(); // (or inject, if you have IoC)
      private BarManager barManager = new BarManager(); // (or inject, if you have IoC)
    
      ... etc
    }
    

    【讨论】:

      【解决方案3】:

      如果你想直接使用A 和B 中的方法代码,你可以让你的C 类包含每个的实例。如果您针对A 和B 的接口进行编码,那么您的客户不需要知道您给他们的是C,而不是A 或B。

      interface IA { void SomeMethodOnA(); }
      interface IB { void SomeMethodOnB(); }
      class A : IA { void SomeMethodOnA() { /* do something */ } }
      class B : IB { void SomeMethodOnB() { /* do something */ } }
      class C : IA, IB
      {
          private IA a = new A();
          private IB b = new B();
          void SomeMethodOnA() { a.SomeMethodOnA(); }
          void SomeMethodOnB() { b.SomeMethodOnB(); }
      }
      

      【讨论】:

        【解决方案4】:

        使用composition:

        class ClassC
        {
            public ClassA A { get; set; }
            public ClassB B { get; set; }   
        
            public C (ClassA  a, ClassB  b)
            {
                this.A = a;
                this.B = b;
            }
        }
        

        然后您可以拨打C.A.DoA()。您还可以将属性更改为接口或抽象类,例如public InterfaceA A 或public AbstractClassA A。

        【讨论】:

          【解决方案5】:

          制作两个接口IA和IB:

          public interface IA
          {
              public void methodA(int value);
          }
          
          public interface IB
          {
              public void methodB(int value);
          }
          

          接下来让A实现IA和B实现IB。

          public class A : IA
          {
              public int fooA { get; set; }
              public void methodA(int value) { fooA = value; }
          }
          
          public class B : IB
          {
              public int fooB { get; set; }
              public void methodB(int value) { fooB = value; }
          }
          

          然后按如下方式实现你的 C 类:

          public class C : IA, IB
          {
              private A _a;
              private B _b;
          
              public C(A _a, B _b)
              {
                  this._a = _a;
                  this._b = _b;
              }
          
              public void methodA(int value) { _a.methodA(value); }
              public void methodB(int value) { _b.methodB(value); }
          }
          

          总体而言,这是一个糟糕的设计,因为您可以让 A 和 B 实现具有相同名称和变量类型(例如 foo(int bar))的方法,您需要决定如何实现它,或者是否您只需在 _a 和 _b 上拨打 foo(bar)。正如其他地方所建议的那样,您应该考虑使用 .A 和 .B 属性,而不是组合这两个类。

          【讨论】:

          • public 不是接口成员定义的有效关键字;-)
          【解决方案6】:

          您可以为A 和B 定义一个基类,您可以在其中保存它们的通用 方法/属性/字段。

          实现C:Base后。

          或者为了模拟多重继承,定义一个通用的interface(s),并在C中实现

          希望这会有所帮助。

          【讨论】:

          • 如果我使用接口,那么我需要在C类中定义方法。有没有其他方法可以直接调用方法?
          • @Virus:你不需要定义所有方法,只需要定义那些你想在不同类型之间共享​​>的方法。
          【解决方案7】:

          您的意思是在这种情况下您希望 C 类成为 A 和 B 的基类。

          public abstract class C
          {
              public abstract void Method1();
          
              public abstract void Method2();
          }
          
          public class A : C
          {
              public override void Method1()
              {
                  throw new NotImplementedException();
              }
          
              public override void Method2()
              {
                  throw new NotImplementedException();
              }
          }
          
          
          public class B : C
          {
              public override void Method1()
              {
                  throw new NotImplementedException();
              }
          
              public override void Method2()
              {
                  throw new NotImplementedException();
              }
          }
          

          【讨论】:

          • 这不是问题的答案
          猜你喜欢
          • 2013-02-19
          • 2016-09-20
          • 1970-01-01
          • 2012-06-17
          • 2011-09-04
          • 1970-01-01
          • 2014-07-14
          • 2011-10-01
          • 2010-09-23
          相关资源
          最近更新 更多