15

正如标题所述,我想知道使用这样的类之间的区别

public class Account
{
    public string Username { get; set; }
    public string Password { get; set; }
}

并像这样使用和界面

public class Account : IAccount
{
    public string Username { get; set; }
    public string Password { get; set; }
}

public interface IAccount
{
    string Username { get; set; }
    string Password { get; set; }
}

我真的很困惑,因为我发现接口没用,因为我可以用它做的所有事情只能使用 Class 来完成,因此,我需要有人为我澄清事情。

4

2 回答 2

22

接口是一种契约:它指定实现接口的类必须具有的成员(方法和属性)。但是因为它只是一个合约,它的任何成员都没有实现。一个类可以实现零个、一个或多个接口。

相比之下:一个是一个......嗯......对象类(如分类学)。例如,anAnimal是一类生物,aGiraffe是一类动物。继承表达了这种关系: anGiraffe 是一个 AnimalwhenGiraffe继承自Animal。它可以做任何动物可以做的事情,甚至更多。它可以为其成员提供实现,并且在 .NET 中,一个类将完全继承自另一个类(Object除非另有说明)。

所以,如果你想表达你的类遵守一个或多个契约:使用接口。但是,您无法提供实现。如果你想表达你的类什么,扩展一个基类。在这种情况下,您可以提供一个实现,但您只能扩展一个基类。


举一个具体的例子:

链表、数组列表、堆栈和字典有一些共同点:它们代表元素的集合。但是它们的实现完全不同。他们唯一的共同点是他们遵守的合同:ICollection. 这意味着你的类可以要求一个集合,任何集合:任何实现的东西ICollection,不管它的实现。

另一方面:汽车、摩托车和卡车也有共同点:它们都是轮式车辆。但他们有更多的共同点:他们都有一个马达,他们都旋转轮胎前进。本质上,它们是Vehicle对象类的成员,并且可以共享(部分)它们的实现。但是,虽然 aTruck可能是 aVehicle a CargoCarrier,但您不能在 C# 中表达这一点。

于 2013-04-07T01:46:15.203 回答
15

基本上:

接口提供contract指定如何与对象对话,但不提供该对象如何处理该请求的细节(除了参数和返回类型等)

和:

一个类(尤其是抽象类)提供了如何与对象对话的信息,但在某些情况下提供了实际的实现(考虑覆盖基类的方法)。

接口允许您定义对象之间的通用通信形式,而无需关心它们如何做事的细节。

一个例子是记录:

public interface ILog
{
   void WriteMessage(string message);
}

public class ConsoleLogger : ILog
{
   public void WriteMessage(string message)
   {
      Console.WriteLine(message);
   }
}

public class MessageBoxLogger : ILog
{
   public void WriteMessage(string message)
   {
      MessageBox.Show(message);
   }
}

public void DoSomethingInteresting(ILog logger)
{
   logger.WriteMessage("I'm doing something interesting!");
}

因为两者都ConsoleLogger实现MessageBoxLoggerILog接口(WriteMessage方法),代码的任何部分都可以在ILog不需要知道它实际做了什么的情况下,他们只关心它做了什么——在这种情况下,写一条日志消息。

所以在上面的代码中,要么 aConsoleLogger要么MessageBoxLogger可以提供给DoSomethingInteresting它根本不重要,因为ILog“知道”如何与该对象交谈。

于 2013-04-07T01:46:04.523 回答