C#中的继承与接口

Inheritance vs. interface in C#

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicates:
Interface vs Base class
When should I choose inheritance over an interface when designing C# class libraries?

所以我在写我第一个真正的C语言程序。这个程序将从四个不同的网站上搜集数据。我的计划是要有一个这样的父类:

1
2
3
4
5
6
class Scraper
{
    string scrapeDate(url);
    string scrapeTime(url);
    //&c.
}

我就有四个班,从中承受。

另一种选择是使Scraper成为一个接口,并有四个类来实现它。

这些方法之间有什么区别?


类继承表示"is-a"关系,例如,TankVehicle关系。如果您的情况至少不满足这一点,那么选择接口而不是继承。

如果建议的基类不为方法提供默认实现,这将是选择接口而不是继承的另一个原因。

在C中,只能从一个类继承,但可以从多个接口继承。这将是选择接口而不是继承的另一个原因。

明白了吗?


在我看来,在可能的情况下,继承是更好的方法。在基类中实现公共特性有助于确保底层实现是一致的,而实现接口只保证接口是一致的。继承尽可能是OOP三脚架的一条腿,并且限制了代码重复。

当我的对象不能或不应该有一个公共的基类,但需要提供类似的功能时,我使用接口。实现公共接口的类可能(也可能)公开附加功能,可能实现多个接口等。

例如:在一个应用程序中,我的数据访问层是围绕"provider"类构建的,它将业务对象和数据库代理对象与数据库隔离开来。在一个实例中,我有一个与SQL Server数据库交互的提供程序,另一个用于与Oracle CRM on Demand通信(aka,why god why)。两者都实现了一个不可知的接口,这样客户机代码就不关心它处理的是哪个数据存储区,也不关心每个数据存储区的工作特性。

Oracle提供程序通过Web服务集合与宿主服务器通信,管理连接会话、批处理请求等。SQL提供程序使用一组存储过程。尽管这两个接口都接受相同的数据类,但Oracle提供程序将数据转换为与它们的深奥(稍微说一下)模式相匹配的模式。通过这个实现,我可以轻松地添加一个提供者来使用XML数据存储、不同的RDBMS或存根/模拟单元测试。

在这种情况下,这些东西拥有一个公共的基类没有多大意义,在一些情况下,这是不可能的。


说实话,两者都要做。

1
2
3
4
5
6
7
8
9
10
11
12
public interface IScraper
{
  string ScrapeDate(string url);
}

public abstract class Scraper : IScraper
{
  public string ScrapeDate(string url)
  {
    // default implementation
  }
}

这两种方法都有好处,但是如果不了解更多关于您的需求,就很难对其进行量化。但是,你没有理由不能两者兼得。为您的类拥有一个接口,这也使得它在测试中是可模拟的。

不过,还需要考虑一些其他问题;如果每个派生类的功能都足够相似,那么简单地使用一个将参数带到构造函数的类可能会更容易。


接口只包含方法、委托或事件的签名。方法的实现在实现接口的类中完成。

一个类可以实现多个接口。

一个类只能有一个直接的基类。


接口允许定义公共行为的结构。

如果可以提取一个或多个特定行为的公共实现,那么继承非常有用。

基本上,如果几个类以相同的方式刮取一个日期,那么将刮取日期放在一个基类中是有意义的;否则,只使用一个接口,并在实现接口的每个类中定义特定的刮取日期。


你在这里所拥有的,实际上是最好的界面。如果您希望包含一些公共逻辑或一些公共数据成员,那么您将使用一个基类并从中继承。您所做的是要求每个孩子实现一组最小的逻辑。


引用抽象类与接口。

There are some similarities and
differences between an interface and
an abstract class:

A class may implement several
interfaces.
A class may inherit only one abstract
class.

An interface cannot provide any code,
just the signature.
An abstract class can provide
complete, default code and/or just the
details that have to be overridden.

An interface cannot have access
modifiers for the subs, functions,
properties etc everything is assumed
as public
An abstract class can contain access
modifiers for the subs, functions,
properties

Interfaces are used to define the
peripheral abilities of a class. In
other words both Human and Vehicle can
inherit from a IMovable interface.
An abstract class defines the core
identity of a class and there it is
used for objects of the same type.

If various implementations only share
method signatures then it is better to
use Interfaces.
If various
implementations are of the same kind
and use common behaviour or status
then abstract class is better to use.

If we add a new method to an Interface
then we have to track down all the
implementations of the interface and
define implementation for the new
method.
If we add a new method to an
abstract class then we have the option
of providing default implementation
and therefore all the existing code
might work properly.

No fields can be defined in interfaces
An abstract class can have fields and
constrants defined


主要区别:

  • 接口根本没有实现,而抽象基类可以实现公共功能
  • 一个类只能从一个基类继承,但它可以实现多个接口

在您的例子中,很可能所有scraper类都需要一些公共特性,所以让它们都继承自公共的基类是有意义的。


如果您有共同的功能,那么您应该使用继承-该功能将在所有子类中都可用,并且每个子类都可以扩展或重写父类代码。

如果您有一些使用类的东西,那么您将使用接口来确保所有类实现相同的方法和属性,但不一定实现相同的功能。