同时拥有抽象类和接口有好处吗?

发布于 2024-07-08 14:39:32 字数 305 浏览 12 评论 0原文

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

创建一个实现 ILogin 接口的抽象基 Login 类并使我的所有具体类都从抽象类继承并在必要时重写是否正确? 原本我以为这样应该不会有什么问题。 然后我开始认为 ILogin 可能是不需要的,因为它可能只会由我的抽象类实现。

同时保留抽象类和接口有好处吗?

谢谢!

I started out with a generic interface called ILogin. The interfaces requires that you implement two properties: UserID and Password. I have many login-type classes that implement this interface. As my project grew and grew, I found that many classes repeated the UserID and Password code. Now I decide that I need a base Login class.

Is it proper to create an abstract base Login class that implements the ILogin interface and have all of my concrete classes just inherit from the abstract class and override when necessary? Originally I was thinking there would be no problem with this. Then I started think that ILogin was probably unneeded because it'll likely only ever be implemented by my abstract class.

Is there a benefit to keeping both the abstract class and the interface around?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

酒绊 2024-07-15 14:39:32

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

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

到目前为止,一切都很好。 现在,假设我们希望为 MosquitoEagle 类提供 Fly() 方法。 由于这两种生物体的相关性并不好(一种是鸟,另一种是昆虫),因此很难为这两种生物找到一个共同的祖先,并将其作为一个抽象类。 这最好通过接口 IFly 来实现。

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

Definitely. Let's think of a concrete example.

Say we have an abstract class Animal.
Say, we make some subclasses Cat, Dog, Mosquito, and Eagle. We can implement its Eat(), Breathe(), Sleep() methods of the abstract class Animal.

So far, so good. Now, let's say we want to have the Fly() method for the Mosquito and Eagle classes. Since these two organisms aren't really well-related (one is a bird, another is an insect) it wouldn't be easy to come up with a common ancestor for the two that we can have as an abstract class. This would best be implemented by an interface IFly.

The IFly interface can have a Fly() method to be implemented. Both Mosquito and Eagle classes can both be subclasses of the abstract class Animal and implement the interface IFly and be able to Eat(), Breathe(), Sleep() and Fly() without having some type of odd ancenstral relationship between the two classes.

蓝眼泪 2024-07-15 14:39:32

我通常在有意义的情况下针对抽象类进行编码,并在每个类(抽象与否)中实现(并在外部契约程序集/库中创建)接口,以便我可以更轻松地实现 Windows Communication Foundation 或 控制反转 必要时(这几乎总是用于模拟)。 这已经成为我的第二天性。

I usually code against abstract classes when it makes sense and implement (and create in an external contracts assembly/library) an interface in every class (abstract or not) so I can more easily implement Windows Communication Foundation or inversion of control when necessary (which is almost always for mocking). This has become second nature for me.

家住魔仙堡 2024-07-15 14:39:32

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

抽象类往往会做到这一点,因此您不必重新实现该功能的某些部分。 Swing 稍微使用了它,它们将有一个接口,然后有一个默认实现,供您仅重写 5 个方法之一,或者它可能会为您添加侦听器,但如果您愿意,则不必使用该基类不想。

Absolutely. The interface is always the correct way to go--that way anything can implement it (including something that already has a parent).

The abstract class tends to make it so you don't have to reimplement some pieces of that functionality. Swing uses it a bit, they will have an interface and then a default implementation for you to override just one of the 5 methods or it might take care of adding listeners for you, but you don't have to use that base class if you don't want to.

梦境 2024-07-15 14:39:32

如果您的抽象类是唯一实现该接口的类,那么您始终可以只检查抽象类的实例,而不需要该接口。 但是,如果您希望与尚未编写的新类(不会扩展抽象类但可以使用接口)兼容,那么现在就继续使用该接口。

If your abstract class is the only class that will ever implement the interface, then you can always just check for instances of the abstract class, you don't need the interface. But if you want to be future-compatible with new classes not yet written which will not extend the abstract class but could use the interface, then keep using the interface now.

天涯沦落人 2024-07-15 14:39:32

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

I agree with cfeduke. I ALWAYS start with interfaces and in the past have used abstract classes that implement interfaces and provide basic functionality to promote code reuse among the classes that inherit from the abstract class. Mocking and IOC are generally speaking interface dependent, for this reason alone I would use interfaces in my designs.

樱桃奶球 2024-07-15 14:39:32

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

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

If the abstract class has functionality, it is wise to keep it. But if it only contains abstract methods and no fields. I see no use in keeping both.

Edit: I work on legacy code with lots of abstract classes. If I ever have the time, I will add the interfaces, (and possibly remove the empty abstracts). Because working with interfaces greatly enhances the possibilities. And they honour their name by exactly defining the interface.

咽泪装欢 2024-07-15 14:39:32

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

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

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

Your interface defines the contract that must be fulfilled for the object to be accepted; your abstract class defines the contract that must be fulfilled AND defines some specific implementation details.

Think of it this way; if you think it's ever possible for anyone to want to fulfill that contract in a different way than the way that the abstract class sketches out (say, with a different backing datatype implementation), then you should have both the interface and the abstract class that implements that.

There's almost no overhead involved in having both the abstract class and the interface; your risk with that approach primarily involves a later coder coming across the interface, not realizing that there's an abstract class that implements the interface, and creating an entire implementation from scratch where it doesn't need to be. I would say that this could be gotten around by specifying in your interface documentation that there is a "default" implementation of the interface in your abstract class; while some coding standards may frown on that practice, I don't see any real problems with it.

太阳男子 2024-07-15 14:39:32

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

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

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

I would always advise that you use interfaces. Abstract classes have the advantage that you can add in default functionality, but requiring that a user use their single inheritance is pretty aggressive.

Microsoft class libraries favour abstract classes over interfaces in a number of cases because it enables them to modify the underlying class. Adding a method to an abstract class rarely breaks someone who inherits from it. Adding a method to an interface always breaks its implementors. However, this provides one of the best reasons for using interfaces: the awful possibility that Microsoft may have already used up your one inheritance.

I would suggest, however, that in your particular case you may wish to revisit the design pattern you are using. It seems unusual to have a lot of "logon-type" classes.

彩扇题诗 2024-07-15 14:39:32

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

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

I think a benefit of keeping the interface would be the ability for future classes to implement multiple interfaces whereas a class can only inherit from one abstract class.

You could extend the functionality of subclasses by creating a new Interface with a different set of methods.

我不在是我 2024-07-15 14:39:32

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

(如果接口的成员与抽象类的成员有任何不同,那么答案当然是肯定的,可能有两者都需要)

...但假设成员是相同的,那么我能想到需要两者的唯一原因是,如果您在不允许多重实现继承的系统中进行编码,那么您的系统中有两个类需要多态相似,但必须从不同的基类继承......

Assuming you are asking specifically when the interface and the abstract class have identical signatures ...

... (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...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文