0

什么被认为是一般的最佳实践:

通过超级类型引用?

public class BirdFeeder{

    public Feed(Bird bird){...}

}

或通过接口

public class BirdFeeder{

    public Feed(IBird iBird){...}

}

就我个人而言,我更喜欢界面,但我不太清楚为什么,对我来说它们只是感觉“更干净”。我想更好地理解为什么我会选择一个而不是另一个。

谢谢

4

3 回答 3

2

您对接口是正确的,它们为您设计继承层次结构提供了更大的灵活性。

假设您有一个从基类开始的层次结构Bird,并向下延伸到各种鸟类。现在假设您想将一只机械鸟添加到鸟类的层次结构中,但您更愿意从Robot基类派生它。如果你的喂食器有Bird争论,你的机械鸟需要一个特殊的喂食器。但是,如果 feeder 接受一个,只要它正确实现了接口,向它IBird发送 a 就没有问题。RoboBirdIBird

于 2012-07-17T01:35:59.933 回答
1

当您想在后代组件中实现一组行为时,请使用抽象类。

当您想要在许多没有有用的共同祖先的类上实现一组行为时的接口。

在很多情况下,您都可以使用其中任何一种。总的来说,我发现我可以重新设计使用界面的设计,获得新的东西,而不会陷入一系列可怕的妥协中。我宁愿定义一个接口,然后让一个抽象类为它的后代实现它,而不是没有接口。一开始的额外工作是微不足道的,但以后会带来巨大的好处。

于 2012-07-17T01:41:07.837 回答
1

如果通过“超级类型”,以及您与接口的比较,我猜您想专注于基本抽象类。(尽管您可以使用非抽象基类,但通常即使是没有抽象成员的抽象类也倾向于向开发人员传达它旨在实现/继承并且不作为一种类型独立存在)

在基类/抽象类与接口方面没有整体的“最佳实践”。他们在设计实践中都有自己的位置。确实,最佳实践来自您正在实施的设计。

就您的设计考虑而言,最大的不同可能是基类/抽象类只能被继承,而接口可以在任何类型的类上实现。

(编辑:pilotcam 提出了一个更好的例子,请参阅他对问题的评论) 从您的鸟类示例中,例如说您想处理不同的鸟类,如 Parrots、Albatross 和 Penguin,它们都继承自Bird. 但是你的应用程序也处理Dinosaur类型。你开始实施Archeopteryx。它是继承自Dinosaur还是继承自Bird?现在,如果改为Bird接口,您可以简单地拥有class Archaeopteryx : Dinsoaur, IBird. 这个例子有点做作(我敢肯定有一个更好的),但希望它足够好。

当然,基类/抽象类也很好。例如,通过组合访问修饰符,您可以利用可能实现的internal方法,您的 API 可以访问实现,但类的外部使用者不能。

确实有很多理由使用一个而不是另一个,而且没有一个是真正“更好”的编码。这实际上取决于您的应用程序设计,并且可以说是您正在编码的隐喻;这些对象代表什么。你的对象实际上是一只鸟,还是它只表现得像一只鸟?你的 API 关心吗?什么会更好地维护您的工作?

这里有更多阅读: 接口与抽象类(一般 OO)(注意所有“链接”的类似问题)

于 2012-07-17T01:35:31.347 回答