如果我不需要所有功能,如何实现接口?

时间:2016-06-08 11:21:45

标签: c#

我定义了一个简单的界面

public interface IBla
{
    public void DoThing();
    public void DoAnotherThing();
    public void Thing();
}

我有一堆实现此接口的类。然而,他们中的许多只需要该接口实现的三个函数中的两个,所以目前我也实现了其余的函数,并将它们留空:如下所示:

public void DoThing(){}

有更优雅的方式吗? 我 NOT 想要为此定义多个接口。 是否有类似“partialInterface”的东西,我不必将该接口的所有函数实现到实现该接口的类中?

由于

6 个答案:

答案 0 :(得分:9)

实现接口时,实现接口的类型必须为所有提供接口详细信息的实现。

除了破坏界面外,不支持部分界面或类似于你想要的东西。

你基本上问“如何在不要求我提供+运算符的情况下实现计算器界面”,简而言之,你不能。根据该界面,它将不再是计算器

您最接近的是您可以创建一个基类,为整个接口或其中的一部分提供默认实现,并继承此基类型,以便继承的类变得更容易到使用较少的代码实现,但提供整个界面。

答案 1 :(得分:2)

我知道你说不想要单独的界面,但是为了将来希望正确回答这个问题的其他人的利益,这是:

您所描述的是将接口分离出来并使用接口继承的点。

public interface IBasic
{
    void DoThing();
}

public interface IAdvanced : IBasic
{
    void DoAnotherThing();
    void Thing();
}

仅需要DoThing的实施仅实施IBasic。需要所有功能的实现实现IAdvanced,其中包括来自IBasic的方法以及其他功能。

答案 2 :(得分:0)

如果您的类没有实现所有方法,那么您可能需要将此接口分成更小的接口 许多特定接口比一个通用接口更好。

创建实现接口的类,抛出NotImplementedException或者什么也不做,看起来像是SOLID规则违规。

答案 3 :(得分:0)

嗯,非常不鼓励只部分实现一个接口,有一种方法可以做到这一点。

大多数答案都谈到将界面分解为多个界面,这是有道理的。但是,如果这是不可能的,只需实现您不想以明确的方式使用的成员,如果它们被调用,您应该抛出NotSupportedException

如果您想查看正在使用的示例,请查看Microsoft自己的代码:http://referencesource.microsoft.com/#mscorlib/system/collections/objectmodel/readonlycollection.cs

void ICollection<T>.Add(T value)
{
    ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}

答案 4 :(得分:0)

鉴于这些事情正在游戏循环中进行处理,可能是IBla的实现类似于玩家角色,敌人,障碍物,导弹等等DoThing等等Move },Fire等等。

如果是这样,那么你的方法是完全有效的。一个不动的对象应该有一个Move方法(所以游戏循环可以调用它),并且因为它不能移动,所以一个空方法是一个有效的实现。

答案 5 :(得分:0)

如果您控制两个接口,则将接口分成多个接口。正如所建议的那样,一个接口可以从另一个接口继承,或者你可以让一些类实现这两个接口。

在这种情况下,接口继承可能是更好的选择,因为您不必修改已经实现更大接口的类。

如果较大的界面是您无法控制的界面,那么将其拆分为多个界面该怎么办?实现接口并留下一些没有实现的方法并不是一个好主意。如果一个类实现了一个接口,那么它应该真正实现该接口。

解决方案是定义您实际需要的较小接口,并创建一个类,使较大的接口适应较小的接口。

假设您有此界面

public interface IDoesFourThings
{
    void DoThingOne();
    void DoThingTwo();
    void DoThingThree();
    void DoThingFour();
}

你想要一个只实现其中两个的课程吗?如果班级真的只做两件事,你就不应该实施IDoesFourThings

首先,创建自己的界面:

public interface IDoesTwoThings
{
    void DoThingA();
    void DoThingB();
}

然后创建一个类,使IDoesFourThings的实现适应您的界面。

public class DoesTwoThingsUsingClassThatDoesFourThings : IDoesTwoThings
{
    private readonly IDoesFourThings _doesFourThings;

    public DoesTwoThingsUsingClassThatDoesFourThings(IDoesFourThings doesFourThings)
    {
        _doesFourThings = doesFourThings;
    }

    public void DoThingA()
    {
        _doesFourThings.DoThingTwo();
    }

    public void DoThingB()
    {
        _doesFourThings.DoThingThree();
    }
}

仅仅为了示例,我避免在IDoesTwoThings中命名方法以匹配IDoesFourThings中的方法。除非它们确实完全相同,否则新界面不需要与旧界面匹配。它是它自己的界面。该类通过使用IDoesFourThings的内部实现来工作是隐藏的。

这与Interface Segregation Principle,我在SOLID中有关。考虑它的一种方法是:接口描述类的功能,但从客户端类的角度来看,它应该描述客户端需要什么。在这种情况下,客户需要两件事,而不是四件。

这种方法非常有用,因为它使我们能够一次处理一个类并推迟其他细节的实现。如果我们正在编写一个类,并且我们意识到它需要一个执行两件事的依赖,我们就可以为这两件事编写接口并让我们的类依赖它。 (现在该类更可测试,因为它依赖于我们可以模拟的接口。)然后,无论我们刚刚创建的那个新接口,我们还可以为它创建一个实现。

这是管理编写代码的复杂性并避免陷入困境的好方法,因为现在我们可以单独负责我们的一个班级,而不用太担心下一个班级和下一个班级将如何工作。 (我们可能知道它们将如何工作,但也许我们不会。无论哪种方式,它都不会减慢我们的速度。)