-2

好的,因此在 C# 中解决多重继承的一种方法是使用接口。尽管这是一个公平的解决方案,但它仍然需要您始终在接口中重新键入实际上不应该在类之间更改的方法。

例如,如果我有一个方法 .foo() 作为接口 Adabo 的一部分,它总是被发现做同样的事情(比如,它循环 10 次),但在开发的某个点我发现我需要做对其进行更改(例如,它实际上应该循环 11 次),我将不得不遍历从 Adabo 继承的每个类并相应地更改它们自己的 .foo() 。

坦率地说,我对接口唯一想要的就是它们在多重继承上的自由通行证。我对他们的全抽象前提并不感兴趣。有没有办法解决这个问题?

4

4 回答 4

3

没有上下文,这是一个很难回答的问题。根据具体情况,不同的解决方案将比其他解决方案更合适。

首先,如其他地方所述 - 接口不指定实现,它们仅指定合同。实现将包含在某个基类中。一个类可以实现许多接口,但你真正的问题(我相信)是;“鉴于不可能进行多重继承,我如何在 C# 类中实现许多接口,同时限制代码重复?”。

有很多选择,上下文很重要。但是,您可以进一步研究一些一般原则;

  • 对象构成;一个班级由其他几个班级组成。例如,一个class car类可以包含几个轮子、一个引擎、门等。轮子类可以在一个class Bus
  • 横切关注点/面向方面的编程;当它是您想要复制的特定行为而不是具体概念时更合适。典型的例子是跟踪/记录;您希望所有方法都记录下来,而不必在任何地方重复记录调用。在 C# 中有出色的工具可以支持这一点,例如PostSharp,但这种方法需要与“传统”OO 设计不同的设计思路。
  • 扩展方法;这是一个 .NET 结构,当您想要实现一个类型的行为而不实际修改该类型时,它非常方便。这里最好的例子是 LINQ;的所有实现都IEnumerable可以使用 LINQ 方法,而无需实际直接实现任何东西。

正如我所说,上下文很重要,没有它,这些只是一般性的指针,可能会在进一步的研究中为您服务。

于 2013-01-26T03:09:57.327 回答
1

在 C# 中解决多重继承的一种方法是使用接口

不对。类实现接口,它们不从它们继承。没有办法在 C#(或任何其他托管语言)中实现多重继承

接近多重继承的一种方法是使用聚合 - 创建一个“包装器”,它只是将函数调用传递回子部分。

如果我有一个方法 .foo() 作为接口 Adabo 的一部分,它总是被发现做同样的事情(比如,它循环 10 次)

接口不做任何事情——它们只是定义具体类需要实现哪些方法/属性。

如果您的问题不仅仅是理论上的,那么我鼓励您发布一些您认为多重继承有价值的示例。可能还有另一种模式可以满足您的需求。

于 2013-01-26T03:00:12.957 回答
1

它仍然要求您始终在接口中重新键入实际上不应该在类之间更改的方法

一点也不。您只需在基类上实现接口,实现将实现该接口的所有类中通用的方法,然后将其余部分声明为abstract - 这会强制派生类实现它。

public interface MyInterface
{
    void SomeCommonMethod(object whatever);

    void SomeSpecialisedMethod(int someOtherParameter);
}

public abstract class MyBaseClass : MyInterface
{
    public void SomeCommonMethod(object whatever)
    {
        //do some stuff
    }

    public abstract void SomeSpecialisedMethod(int someOtherParameter);
}

public class SomeSpecialisedClass : MyBaseClass
{
    public override void SomeSpecialisedMethod(int someOtherParameter)
    {
        //do stuff that can't be done in the base class
    }
}

这显示了如何避免在所有需要它的类中无休止地“重新键入”接口实现。

话虽如此,使用接口并不等同于多重继承。在 C# 的早期,对此有很多讨论,普遍的共识是,在现实世界中实际上很少需要多重继承。我个人在我的职业生涯中只真正需要过几次,在这些情况下,有足够的解决方法——多重继承本来是一种更清洁的方法。

我唯一想要的接口是它们在多重继承时的自由通行证

跟我重复一遍:   接口中也没有多重继承。

一个接口可以实现多个其他接口,也可以定义自己的需求(契约),但绝不是继承。您可以近似多重继承,但无法实现正确的多重继承。

于 2013-01-26T03:07:21.527 回答
1

似乎您混淆了几件事并感到困惑。如果我理解正确,你有一个接口,比如 Adabo,它有一个名为 foo() 的方法。现在,您有许多实现此方法的类。从您写的内容来看,我认为该方法的实现在所有这些类中都是相同的,因此,困扰您的是,当您想要更改实现时,您需要去更改所有这些。

好吧,这是你的问题。接口中的方法适用于不同实现类的情况,根据自己的需要以不同的方式实现它。如果碰巧实现对所有人都是一样的。那么你有几个选择:

  1. 继承:通过具体或抽象类。将公共方法放在父类中,并对其进行扩展。如果您说子类已经扩展了其他类。那么你的下一个赌注是,

  2. 组合:将通用功能放在一个组件类中,并包含在其他需要使用它的类中。因此,使用 Adabo 类代替接口 Adabo

    类阿达博{

    foo();
    

    }

那么在你所有的孩子班里都有

class childA {

   Adabo a;

   ...
   a.foo();
}

class childB {

   Adabo a;

   ...
   a.foo();
}

class childC {

   Adabo a;

   ...
   a.foo();
}
于 2013-01-26T03:47:24.737 回答