java中抽象类和接口的最佳实践
因此,您已经有了一个接口和一个实现接口中方法的子集的抽象类。您还拥有一些继承抽象类并提供抽象类未提供的方法的实现的类。
那么这里的最佳实践是什么?我说的是这样的问题:
1)抽象类应该实现接口还是它的子类?每节课都应该吗?在我看来,抽象类就应该如此。当然,所有的类都可以实现该接口,但这似乎是多余的,因为抽象的子类将“继承”该接口,因为它们扩展了抽象类。
2)考虑到抽象类实现了接口的部分内容,它是否也应该为它没有实现的方法声明抽象方法?在我看来,这是正确的,但在某种程度上,这似乎是多余的,因为抽象的子级将需要实现这些方法才能进行编译。
那么您对最佳实践的看法是什么?问题归结为:我们有一个接口,它定义了我们希望某些类执行的操作,我们有接口中定义常见行为的方法的子集,并且我们有几种不同的方法来定义不常见的行为。布置这个问题的最佳方式是什么?
So you've got an interface and an abstract class that implements a subset of the methods in the interface. You've also got some classes that inherit the abstract class and give implementations of the methods the abstract class doesn't give.
So what's the best practice here? I'm talking about issues like:
1) Should the abstract class implement the interface or should its child classes? Should every class? It seems to me that just the abstract class should. Of course, all of the classes could implement the interface, but that seems redundant because the children of the abstract will 'inherit' the interface because they extend the abstract class.
2) Given that the abstract class implements parts of the interface, should it also declare abstract methods for the methods it doesn't implement? It seems to me like this is right, but in a way this seems redundant because the children of the abstract will need to implement these methods in order to compile.
So what are your arguments for the best practice? The question boils down to: we've got an interface that defines what we want some classes to do, we've got a subset of the methods in the interface that define common behavior, and we've got a few different ways to define the non-common behavior. What's the best way to lay this out?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这里应该对您有所帮助的原则是 DRY:不要重复自己(http://en.wikipedia .org/wiki/Don%27t_repeat_yourself)。
在这种情况下,DRY 意味着您不应该做不必要的工作。
因此,对于您的第一个问题,抽象类应该实现接口,因为它可以使您免于在每个具体类中重复“implements X”子句。
至于第二个问题,在实现它的抽象类中重复接口方法是没有意义的。这是多余的工作。此外,当接口演变/更改时,您将需要更改抽象类中的对应(抽象)方法,这是一个令人头痛的问题。在某些时候,您会错过更新某些方法,而具体类将需要徒劳地实现这些方法。
The principle that should help you here id DRY: Don't Repeat Yourself (http://en.wikipedia.org/wiki/Don%27t_repeat_yourself).
In this context, DRY means that you should not do unnecessary work.
So for your 1st question the abstract class should implement the interface because it saves you from repeating the "implements X" clause at every concrete class.
As for the 2nd question, there's no point in repeating the interface methods in the abstract class that implements it. This is redundant work. Moreover when the interface evolves/changes you will need to change the counterparts (abstract) methods at the abstract class which is a headache. At some point you'll miss updating some of the method and the concrete class will need to implement these in vain.
抽象类应该实现接口,并提供公共成员函数的具体实现。 IIRC 它不需要为它未实现的元素声明抽象方法,因为假设这些方法需要由子类实现。
The abstract class should implement the interface, and provide concrete implementations of common member functions. IIRC it shouldn't need to declare abstract methods for the elements it doesn't implement, as these are assumed to be needed to be implemented by subclasses.
为此进行编程的最灵活的方法是:
让具体类实现接口是没有意义的(稍后会详细介绍)。
让抽象类重复接口中的抽象方法是没有意义的。
通过执行#4,您可以确保可以使用实现该接口的所有类 - 如果您要使用抽象类,则不能使用实现该接口但不扩展抽象类的类。
(后面部分)
让抽象类和具体类实现接口的一个论点是,如果您稍后要更改具体类以不再扩展抽象类,那么您可能会忘记实现该接口,在在某些情况下,可能会破坏代码而编译器不会抱怨。我不知道我对这个争论有何感想。
The most flexible way to program for this is:
There is no point in having the concrete classes implement the interface (more later).
There is no point in having the abstract class repeat the abstract methods from the interface.
By doing #4 you ensure that all classes that implement the interface can be used - if you were to use the abstract class instead then classes that implement the interface but do not extend the abstract class cannot be used.
(later part)
The one argument for having the abstract class AND the concrete classes implement the interface is that if you were to later change the concrete class to no longer extend the abstract class then you could forget to also implement the interface, which, in some cases, could break the code without the compiler complaining. I don't know how I feel about that argument.
接口方法是隐式抽象的,因此如果抽象类实现了接口,则无需满足抽象类中的接口契约。抽象接口在技术上是合法的,但也是多余的。抽象类可以实现接口,只要所有子类都实现该接口即可,但抽象类不应包含已实现的方法。
接口方法是特定于实现的(对于实现类来说是唯一的),而抽象状态和行为是通用的,或者在实现之间共享。将接口方法实现为通用功能是一个矛盾的说法。
关键问题是您打算如何处理接口实现?如果除了定义附加契约之外,基本接口不用于任何其他用途,我会说只需将抽象方法添加到抽象类中,否则该接口是多余的开销。如果您发现一个用例需要访问接口方法,但不一定是通用功能,那么也许接口是值得的。
Interface methods are implicitly abstract, so if an abstract class implements an interface, there is no need to satisfy the interface contract in the abstract class. An abstract interface is technically legal, but also redundant. It is fine for an abstract class to implement an interface as long as all subclasses would otherwise implement the interface, but the abstract class should not contain the implemented methods.
Interface methods are implementation specific (unique to the implementing class), whereas abstract states and behaviours are meant to be common, or shared amongst implementations. It would be an oxymoron to implement interface methods as common functionality.
The key question is what do you plan on doing with the interface implementations? If the base interface isn't used for anything besides defining an additional contract, I would say simply add abstract methods to the abstract class, otherwise the interface is redundant overhead. If you find a use case where you would want access to the interface methods, but not necessarily the common functionality, then maybe an interface is worthwhile.
接口的实现是否比抽象类或其子类更多?您的设计需要界面吗?否则,该界面对您的设计没有任何贡献,我建议您干脆摆脱它。
当涉及到您的明确问题时,抽象类应该实现该接口。扩展抽象类的类不应该这样做。
您不应该在接口中已有的抽象类中多余地声明抽象方法。
Do you have more implementations of the interface than the abstract class or subclasses thereof? Do your design need the interface? Otherwise, the interface contributes nothing to your design, and I suggest you simply get rid of it.
When it comes to your explicit questions, the abstract class should implement the interface. Classes extending the abstract class shouldn't.
You shouldn't redundantly declare abstract methods in the abstract class that already is in the interface.