11

我从一个名为 ILogin 的通用接口开始。这些接口要求您实现两个属性:UserID 和 Password。我有许多实现此接口的登录类型类。随着我的项目越来越大,我发现许多类都重复了 UserID 和 Password 代码。现在我决定我需要一个基本的登录类。

创建一个实现 ILogin 接口的抽象基本登录类并让我的所有具体类只从抽象类继承并在必要时覆盖是否合适?本来我以为这样不会有问题的。然后我开始认为 ILogin 可能是不需要的,因为它可能只会由我的抽象类实现。

保留抽象类和接口是否有好处?

谢谢!

4

10 回答 10

15

确实。让我们考虑一个具体的例子。

假设我们有一个抽象类Animal。比如说,我们创建了一些子类CatDogMosquitoEagle。我们可以实现它Eat()的抽象类的Breathe()方法。Sleep()Animal

到现在为止还挺好。现在,假设我们想要拥有and类的Fly()方法。由于这两种生物的关系并不密切(一种是鸟,另一种是昆虫),因此很难为我们可以作为抽象类拥有的两种生物找到共同的祖先。这最好由一个接口来实现。MosquitoEagleIFly

IFly接口可以具有Fly()要实现的方法。MosquitoEagle类都可以是抽象类的子类并Animal实现接口,并且IFly能够在两个类之间不存在某种奇怪的祖先关系。Eat()Breathe()Sleep()Fly()

于 2008-11-05T23:20:42.063 回答
4

我通常在抽象类有意义时对抽象类进行编码,并在每个类(抽象或非抽象)中实现(并在外部合同程序集/库中创建)一个接口,因此我可以在必要时更轻松地实现 Windows Communication Foundation 或控制反转(这几乎总是用于嘲笑)。这已经成为我的第二天性。

于 2008-11-05T22:58:46.057 回答
2

绝对地。接口始终是正确的方法——这样任何东西都可以实现它(包括已经有父对象的东西)。

抽象类倾向于做到这一点,因此您不必重新实现该功能的某些部分。Swing 使用了一点,它们将有一个接口,然后是一个默认实现,供您仅覆盖 5 种方法中的一种,或者它可能会为您添加侦听器,但您不必使用该基类,如果您不想。

于 2008-11-05T22:59:04.447 回答
2

如果您的抽象类是唯一实现接口的类,那么您总是可以只检查抽象类的实例,您不需要接口。但是,如果您希望将来与尚未编写的新类兼容,这些新类不会扩展抽象类但可以使用接口,那么现在继续使用接口。

于 2008-11-05T23:10:10.713 回答
1

如果抽象类具有功能,那么保留它是明智的。但是如果它只包含抽象方法而没有字段。我认为保留两者没有用。

编辑:我处理带有大量抽象类的遗留代码。如果我有时间,我会添加接口,(并可能删除空的摘要)。因为使用接口极大地增加了可能性。他们通过精确定义接口来尊重他们的名字。

于 2008-11-05T22:55:53.127 回答
1

我同意cfeduke。我总是从接口开始,过去使用实现接口并提供基本功能的抽象类来促进从抽象类继承的类之间的代码重用。Mocking 和 IOC 通常是依赖于接口的,仅出于这个原因,我会在我的设计中使用接口。

于 2008-11-05T23:11:10.413 回答
1

您的接口定义了要被接受的对象必须履行的合同;您的抽象类定义了必须履行的合同并定义了一些具体的实现细节。

这样想;如果您认为任何人都可能希望以不同于抽象类草拟的方式(例如,使用不同的支持数据类型实现)来履行该合同,那么您应该同时拥有接口和抽象类实现这一点。

同时拥有抽象类和接口几乎没有任何开销;这种方法的风险主要涉及后来的编码人员遇到接口,没有意识到有一个实现接口的抽象类,并在不需要的地方从头开始创建整个实现。我想说这可以通过在你的接口文档中指定你的抽象类中有一个接口的“默认”实现来解决;虽然一些编码标准可能不赞成这种做法,但我认为它没有任何真正的问题。

于 2008-11-06T00:38:25.603 回答
0

我总是建议你使用接口。抽象类的优点是您可以添加默认功能,但要求用户使用它们的单一继承是非常激进的。

在许多情况下,Microsoft 类库偏爱抽象类而不是接口,因为它使它们能够修改底层类。向抽象类添加方法很少会破坏从它继承的人。向接口添加方法总是会破坏其实现者。但是,这提供了使用接口的最佳理由之一:Microsoft 可能已经用完您的一个继承。

但是,我建议在您的特定情况下,您可能希望重新审视您正在使用的设计模式。有很多“登录类型”类似乎是不寻常的。

于 2008-11-05T23:15:03.450 回答
0

我认为保留接口的好处是未来类能够实现多个接口,而一个类只能从一个抽象类继承。

您可以通过使用一组不同的方法创建一个新接口来扩展子类的功能。

于 2008-11-05T23:16:08.203 回答
0

假设您特别询问接口和抽象类何时具有相同的签名......

... (If the members of the Interface are different in any way from the members of the abstract class then of course the answer is yes, there may be a need for both)

... but assuming the members are identical, then the only reason I can think of to need both is if you're coding in a system that does not allow multiple implementation inheritance there are two classes in your system that need to be polymorphically similar, but must inherit from different base classes...

于 2008-11-06T00:55:10.143 回答