【问题标题】:Multiple inheritance using interaces使用接口的多重继承
【发布时间】:2021-06-23 06:42:32
【问题描述】:

请看附图。

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

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

我该如何填写“???”在“头班”? 我很高兴有任何意见。提前谢谢!

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,描述了如何使用接口。但这并不能解决上述问题。

【问题讨论】:

  • 天哪。没有反馈的“-1”!你怎么敢!我可以要求您提供反馈,说明您为什么给我那个“-1”,或者再次删除它并且不要再看这篇文章。我尽量不问愚蠢的问题,有时问正确的问题并不容易,有时问题也不是简单的而是复杂的。那么,为什么是“-1”?

标签: c# interface multiple-inheritance abstraction


【解决方案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();
}

【讨论】:

  • 是的,差不多。我只是想摆脱链接 public void Method_1() => _a.Method_1(); 的方法或者这可能是最低限度的?
  • @RadioMan85 您可以尝试为此使用默认接口方法(我个人不会这样做,也取决于实际实现),但除此之外我不知道很多选项。看起来你想要一些不属于 C# 的特性/mixins。
  • 好像我想要一些类似 traits/mixins 的东西(还不知道这些词)。
【解决方案2】:

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();
    }

}

【讨论】:

  • 是的,我认为这是我目前不喜欢的方法,因为有多余的代码。但我想我必须在这两种解决方案之间做出选择。谢谢您的意见。
【解决方案3】:

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

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直接存在,只知道接口。

我相信这叫做策略模式?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-24
    • 1970-01-01
    • 1970-01-01
    • 2014-12-31
    • 1970-01-01
    • 2010-11-30
    相关资源
    最近更新 更多