我开始使用名为ILogin的通用接口。接口要求您实现两个属性:UserID和Password。我有许多实现此接口的登录类型。随着我的项目的成长和发展,我发现许多类重复了UserID和Password代码。现在我决定我需要一个基本的登录类。
创建一个实现ILogin接口的抽象基类Login类是否合适,并且我的所有具体类都是从抽象类继承并在必要时覆盖?最初我觉得这没问题。然后我开始认为ILogin可能是不必要的,因为它可能只能由我的抽象类实现。
保持抽象类和接口都有好处吗?
谢谢!
答案 0 :(得分:15)
当然。让我们想一个具体的例子。
假设我们有一个抽象类Animal
。
比如说,我们制作了一些子类Cat
,Dog
,Mosquito
和Eagle
。我们可以实现抽象类Eat()
的{{1}},Breathe()
,Sleep()
方法。
到目前为止,这么好。现在,假设我们想要Animal
和Fly()
类的Mosquito
方法。由于这两种生物并不是真正相关的(一种是鸟类,另一种是昆虫),因此我们可以将这两种生物作为一个抽象的类来提出共同的祖先并不容易。最好通过接口Eagle
实现。
IFly
接口可以实现IFly
方法。 Fly()
和Mosquito
类都可以是抽象类Eagle
的子类,并实现接口Animal
并且能够IFly
,Eat()
,Breathe()
和Sleep()
,两个类之间没有某种类型的奇怪的祖先关系。
答案 1 :(得分:4)
我通常在有意义的情况下对抽象类进行编码,并在每个类(抽象或非抽象)中实现(并在外部契约程序集/库中创建)一个接口,这样我就可以更轻松地实现Windows Communication Foundation或{{3}必要时(几乎总是用于嘲笑)。这已成为我的第二天性。
答案 2 :(得分:2)
绝对。接口始终是正确的方式 - 任何事情都可以实现它(包括已经拥有父项的东西)。
抽象类倾向于实现它,因此您不必重新实现该功能的某些部分。 Swing稍微使用它,它们将有一个接口,然后是一个默认实现,您可以只覆盖5个方法中的一个,或者它可能会为您添加监听器,但如果您不必使用该基类不想。
答案 3 :(得分:2)
如果您的抽象类是 only 类,它将实现该接口,那么您始终可以只检查抽象类的实例,而不需要该接口。但是如果你想与未编写的新类兼容,这些类不会扩展抽象类但可以使用接口,那么现在继续使用该接口。
答案 4 :(得分:1)
如果抽象类具有功能,那么保留它是明智的。但如果它只包含抽象方法而没有字段。我认为两者都没用。
编辑:我处理包含大量抽象类的遗留代码。如果我有时间,我将添加接口,(并可能删除空的摘要)。因为使用接口大大增强了可能性。他们通过精确定义界面来尊重他们的名字。
答案 5 :(得分:1)
我同意cfeduke。我总是从接口开始,并且在过去使用了实现接口的抽象类,并提供了基本功能,以促进从抽象类继承的类之间的代码重用。 Mocking和IOC一般都是依赖于接口的,仅仅因为这个原因我会在我的设计中使用接口。
答案 6 :(得分:1)
您的界面定义了要接受的对象必须满足的合同;您的抽象类定义了必须履行的契约,并定义了一些特定的实现细节。
以这种方式思考;如果您认为任何人都希望以不同于抽象类概述的方式(例如,使用不同的支持数据类型实现)来实现该契约,那么您应该同时拥有接口和抽象类实现了。
同时拥有抽象类和接口几乎没有任何开销;使用该方法的风险主要涉及后来的编码器来到接口,没有意识到有一个实现接口的抽象类,并且从头开始创建一个不需要的整个实现。我想说这可以通过在您的接口文档中指定抽象类中的接口的“默认”实现来解决;虽然一些编码标准可能不赞成这种做法,但我认为没有任何实际问题。
答案 7 :(得分:0)
我总是建议你使用接口。抽象类的优点是您可以添加默认功能,但要求用户使用其单一继承是非常积极的。
Microsoft类库在很多情况下都支持抽象类而不是接口,因为它使它们能够修改底层类。向抽象类添加方法很少会破坏从中继承的人。向接口添加方法总是会破坏其实现者。但是,这提供了使用接口的最佳原因之一:微软可能已经用尽了你的一个继承。
但是,我建议您在特定情况下重新考虑您正在使用的设计模式。拥有大量“登录类型”类似乎很不寻常。答案 8 :(得分:0)
我认为保持接口的好处是将来的类能够实现多个接口,而类只能从一个抽象类继承。
您可以通过使用一组不同的方法创建新接口来扩展子类的功能。
答案 9 :(得分:0)
假设您具体询问接口和抽象类何时具有相同的签名...
...(如果接口的成员与抽象类的成员有任何不同,那么当然答案是肯定的,可能需要两者)
...但是假设成员是相同的,那么我认为需要两者的唯一原因是如果你在一个不允许多个实现继承的系统中编码,你的系统中有两个类需要在多态上相似,但必须从不同的基类继承......