使用接口的多重继承

时间:2021-03-26 12:23:19

标签: c# interface multiple-inheritance abstraction

请考虑附图。

我想要的是(技术上的)“用户”可以通过“HeadClass”的实例化使用来自 A、B 或 C 类的方法。我试图避免的是,我必须为 A、B 和 C 类中定义的每个方法添加一个单独的函数,以通过“HeadClass”调用它们。我昨天试图在另一个 stackoverflow 请求中描述这一点,但已将其删除,因为似乎不清楚我想要实现什么。所以这是另一种方法。

通常这将通过继承来实现(如果只继承一个类)。但是,正如他们在删除的帖子中告诉我的那样,我应该改用 Interface。现在,到目前为止我认为我知道接口是如何工作的(几乎每个类都使用),但我无法弄清楚我是如何实现这个描述问题的。

我必须如何填写“???”在“头等舱”? 我很高兴有任何意见。提前谢谢!

The Problem

class User
{
    public User(IHeadClass headObj)
    {
        _headObj = headObj
    }

    public DoStuff()
    {
        _headObj.Method_1
        _headObj.Method_2
        _headObj.HeadMethod
    }
    
    
}


public class HeadClass : IHeadClass, ???
{
    ???

    public HeadClass( ??? )
    {
        ???
    }

    void HeadMethod()
    {
        ... do head stuff
    }
}


public class Class_A : IClass_A
{
    public void Method_1 () { }
}


public class Class_B : IClass_B
{
    public void Method_2 () { }     
    public void Method_3 () { }
}

public class Class_C : IClass_C
{
    public void Method_4 () { }
}

我查看了 this 描述如何使用接口。但这并不能解决上述问题。

3 个答案:

答案 0 :(得分:1)

如果我理解正确,您可以在这里使用组合。像这样:

public interface IClass_A
{
    void Method_1 ();
}

public interface IClass_B
{
    void Method_2 ();
    void Method_3 ();
}

public interface IClass_C
{
    void Method_4 ();
}


public interface IHeadClass : IClass_A, IClass_B, IClass_C
{
    void HeadMethod();
}

public class HeadClass : IHeadClass
{
    private readonly IClass_A _a;
    private readonly IClass_B _b;
    private readonly IClass_C _c;

    public HeadClass(IClass_A a, IClass_B b, IClass_C c)
    {
        _a = a;
        _b = b;
        _c = c;
    }

    void HeadMethod()
    {
        ... do head stuff
    }

    public void Method_1() => _a.Method_1();

    public void Method_2() =>  _b.Method_2();
    public void Method_3() =>  _b.Method_3();

    public void Method_4() => _c.Method_4();
}

答案 1 :(得分:1)

C#(与 C++ 或 PHP 不同)不支持多重继承。接口允许多重继承,但不提供方法的定义,只提供声明。

我认为解决方案可能是称为 fasade 的模式:在 HeadClass 中编写方法来调用其他类中的方法。在这种情况下,不需要接口。

public class HeadClass
{
    private Class_A _a;
    private Class_B _b;
    private Class_C _c;

    public HeadClass( Class_A a, Class_B b, Class_C c )
    {
        _a=a;
        _b=b;
        _c=c;
    }

    void HeadMethod()
    {
        ... do head stuff
    }

    public void Method_1 () {
        _a.Method_1();
    }
    public void Method_2 () {
        _b.Method_2();
    }
    public void Method_3 () {
        _b.Method_3();
    }
    public void Method_4 () {
        _c.Method_4();
    }

}

答案 2 :(得分:0)

我可以建议您在构造函数中传递一个接口而不是类定义吗?

public class HeadClass
{
    private IMethod1 _method1;
    private IMethod2 _method2;
    private IMethod3 _method3;
    private IMethod4 _method4;

    public HeadClass( IMethod1 method1, IMethod2 method2, IMethod3 method3, IMethod4 method4)
    {
        _method1=method1;
        _method2=method2;
        _method3=method3;
        _method4=method4;
    }

    void HeadMethod()
    {
        ... do head stuff
    }

    public void Method_1 () {
        _method1.Method_1();
    }
    public void Method_2 () {
        IMethod2.Method_2();
    }
    public void Method_3 () {
        IMethod3.Method_3();
    }
    public void Method_4 () {
        IMethod4.Method_4();
    }

}

现在您已经移除了与类的任何直接耦合,您不仅可以通过接口进行链接。

假设您想将方法 2 和 3 拆分为它自己的两个类?此代码,永远不必更改。

您现在可以重用任何具有接口定义的类作为参数。没有代码被定义两次,在每个输入中做同样的事情。

因为:

public class Method1 : IMethod1
{

}

public class Method2 : IMethod2
{

}

public class Method3 : IMethod3
{

}

public class Method4 : IMethod4
{

}

can now be parsed as parameters to HeadClass.

or, if you insist method 2 & 3 belong on the same class.

public class ClassA: IMethod1
{

}

public class ClassB: IMethod2, IMethod3
{

}

public class ClassC: IMethod4
{

}

从这个例子应该可以看出,好处在于你现在可以在Headclass中为所欲为,如果你需要改变行为,可以通过构造函数注入代码,而不必重试headclass的行为.

和headclass,不知道ClassA、B或C直接存在,只知道接口。

我相信这被称为策略模式吗?