接口继承接口

时间:2014-05-21 14:14:42

标签: c# inheritance

我有一个层次结构。

public interface IIncomingMessage : IMessage
{
    String Source { get; set; }
    void ProcessMessage();
}


public interface IOutgoingMessages : IMessage
{
    void SendMessage();
}

我有一个使用Static CreateMessage方法生成我的消息的客户端。

IMessage message = MessageFactory.CreateMessage("incomingA");
messageA.ProcessMessage();

然而,我能做到这一点的唯一方法是将ProcessMessage()添加到IMessage。但是,如果我这样做,那么我必须在IOutgoingMessage中实现它。

现在,当我写这篇文章时,我发现我可以摆脱IMessage ......我应该吗?或者有更好的方法吗?

4 个答案:

答案 0 :(得分:4)

根据您使用CreateMessage工厂的方式,您希望ProcessMessage是所有IMessage类型的常用方法。根据您希望代码的工作方式,我会说IMessage应该定义ProcessMessage方法接口。

但是,在查看一小段代码时,在我看来,您的意图并不是始终处理消息,而只是在IIncomingMessage实现时才这样做。所以你的工厂方法不会起作用。 T. Kiley建议使用CreateInboundMessageCreateOutboundMessage两种工厂方法可能更有意义,因为您对这两种类型的消息都有不同的行为。然后,这些方法将返回IIncomingMessage和'IOutgoingMessage`实例,然后您可以处理它们或相应地处理它们。

目前,

IMessage被用作标记界面。如果您认为有必要 - 无论是对泛型的限制(例如MyCollection<T> where T : IMessage),请保留它。但如果它真的没有描述行为或一组共同的属性/方法,或者它不是用作有用的标记,那么我不确定它提供了什么好处。

同样,这只是基于看到一些代码。我假设幕后有更多的行为和功能。祝你好运!!

答案 1 :(得分:1)

我将尝试通过提供此场景的另一个示例进行简化:

public class Animal
{
    void Run();
}

public class Giraffe : Animal
{
    void ExtendNeck();
}

public class Monkey : Animal
{
    void EatBanana();
}

现在可以将EatBanana()添加到Animal了吗?正如您自己注意到的那样,并非所有IMessage个实现者ProcessMessage(),并且在此示例中并非所有动物EatBanana()。什么是完成你想要做的事情的另一种方式?如果您的类之间有共同的功能,则只能使用IMessage。如果您没有,则不需要接口。考虑到YAGNI。如果有共同的功能,您可以稍后添加它。如果您要创建IncomingMessage并调用IncomingMessage特定方法,则只需创建一个强类型IncomingMessage并使用它。您甚至可能不需要静态工厂方法。

答案 2 :(得分:0)

您可以使用不继承任何内容的不同类,并完全分离该过程。如果你这样做,你将失去在这种情况下使用子类的几个优点。它们之间可能存在类似的属性,如果它们都扩展了一个公共类,它将更容易引用一个与另一个相对。至于你对这些子类的方法问题,你可以简单地让你的父类声明一个公共方法(让它称之为ProcessMessage()),并简单地让每个子类覆盖这种方法的行为。这样您就不需要使用不同的方法,只需要两种不同的定义。简单的多态概念。

答案 3 :(得分:0)

(假设&#39; MessageFactory.CreateMessage(&#34; incomingA&#34;)&#39;返回类型为IIncomingMessage的对象)

使用var

var message = MessageFactory.CreateMessage("incomingA");
message.ProcessMessage();

或投射结果

IMessage message = MessageFactory.CreateMessage("incomingA");

     if (!(message is IIncommingMessage))
        throw new InvalidOperationException();

     (message as IIncommingMessage).ProcessMessage();