问题描述
我读过的几乎每本Java书都谈论使用界面作为一种在对象之间共享状态和行为的方式,而当第一次"构造"似乎没有共享关系时.
但是,每当我看到Architects设计一个应用程序时,他们要做的第一件事就是开始编程到接口.怎么会?您如何知道该接口中会发生的对象之间的所有关系?如果您已经知道这些关系,那么为什么不扩展抽象类呢?
推荐答案
编程到接口是指使用该接口创建的"合同".因此,如果您的IPoweredByMotor接口具有start()方法,即实现接口的未来类,无论是MotorizedWheelChair,Automobile或SmoothieMaker,在实现该接口的方法时,都会为系统添加灵活性,因为一件代码可以启动许多不同类型的事物的电动机,因为一件代码需要知道的只是它们响应start(). 他们如何开始都没关系,只是他们必须启动.
其他推荐答案
很棒的问题.我会推荐您访问 Josh Bloch在有效的Java中(第16项)为什么更喜欢在抽象类中使用接口.顺便说一句,如果您还没有这本书,我强烈推荐它!这是他所说的摘要:
- 现有类可以轻松改进以实现新接口.您需要做的就是实现接口并添加所需的方法.现有类无法轻松翻新以扩展新的抽象类.
- 接口是定义混合插入的理想选择.混合接口允许类声明其他可选行为(例如,可比).它允许将可选功能与主要功能混合.抽象类无法定义混合插入 - 一个类不能扩展超过一个父.
- 接口允许非层次结构框架.如果您的类具有许多接口功能的类,则可以实现它们.如果没有接口,您将必须为各种属性组合创建一个blo肿的类层次结构,从而导致组合爆炸.
- 接口启用安全功能增强功能.您可以使用装饰器图案创建包装器类,这是一种健壮且灵活的设计.包装器类实现并包含相同的接口,将一些功能转发到现有方法,同时将专业行为添加到其他方法.您不能使用抽象方法做到这一点 - 您必须使用继承,这更脆弱.
提供基本实现的抽象类的优势如何?您可以为每个接口提供一个抽象的骨骼实现类.这结合了接口和抽象类的优点.骨骼实施提供了实施援助,而无需施加严重的限制,即当它们用作类型定义时,它们会抽象级别的力量.例如, Collections Framework 使用接口和界面和类型定义该类型为每一个提供骨骼实现.
其他推荐答案
编程到接口提供了几个好处:
-
GOF类型模式需要,例如访问者模式
-
允许替代实现.例如,单个接口可能存在多个数据访问对象实现,该接口抽象使用中的数据库引擎(AccountDaomySQL和AccountDaooracle都可以实现AccountDao)
-
类可以实现多个接口. Java不允许多次继承具体类.
-
摘要实现详细信息.接口可能仅包括公共API方法,隐藏实现详细信息.好处包括已记录的公共API和有记录的合同.
-
由现代依赖注入框架大量使用,例如 http://www.springframework.org/.
-
在Java中,可以使用界面来创建动态代理 - http://static.springframework.org/spring/docs/2.5.x/reference/aop.html .
-
模拟实现,单元测试 - 当相关类是接口的实现时,可以编写模拟类,也可以实现这些接口.模拟类可用于促进单位测试.
问题描述
Almost every Java book I read talks about using the interface as a way to share state and behaviour between objects that when first "constructed" did not seem to share a relationship.
However, whenever I see architects design an application, the first thing they do is start programming to an interface. How come? How do you know all the relationships between objects that will occur within that interface? If you already know those relationships, then why not just extend an abstract class?
推荐答案
Programming to an interface means respecting the "contract" created by using that interface. And so if your IPoweredByMotor interface has a start() method, future classes that implement the interface, be they MotorizedWheelChair, Automobile, or SmoothieMaker, in implementing the methods of that interface, add flexibility to your system, because one piece of code can start the motor of many different types of things, because all that one piece of code needs to know is that they respond to start(). It doesn't matter how they start, just that they must start.
其他推荐答案
Great question. I'll refer you to Josh Bloch in Effective Java, who writes (item 16) why to prefer the use of interfaces over abstract classes. By the way, if you haven't got this book, I highly recommend it! Here is a summary of what he says:
- Existing classes can be easily retrofitted to implement a new interface. All you need to do is implement the interface and add the required methods. Existing classes cannot be retrofitted easily to extend a new abstract class.
- Interfaces are ideal for defining mix-ins. A mix-in interface allows classes to declare additional, optional behavior (for example, Comparable). It allows the optional functionality to be mixed in with the primary functionality. Abstract classes cannot define mix-ins -- a class cannot extend more than one parent.
- Interfaces allow for non-hierarchical frameworks. If you have a class that has the functionality of many interfaces, it can implement them all. Without interfaces, you would have to create a bloated class hierarchy with a class for every combination of attributes, resulting in combinatorial explosion.
- Interfaces enable safe functionality enhancements. You can create wrapper classes using the Decorator pattern, a robust and flexible design. A wrapper class implements and contains the same interface, forwarding some functionality to existing methods, while adding specialized behavior to other methods. You can't do this with abstract methods - you must use inheritance instead, which is more fragile.
What about the advantage of abstract classes providing basic implementation? You can provide an abstract skeletal implementation class with each interface. This combines the virtues of both interfaces and abstract classes. Skeletal implementations provide implementation assistance without imposing the severe constraints that abstract classes force when they serve as type definitions. For example, the Collections Framework defines the type using interfaces, and provides a skeletal implementation for each one.
其他推荐答案
Programming to interfaces provides several benefits:
Required for GoF type patterns, such as the visitor pattern
Allows for alternate implementations. For example, multiple data access object implementations may exist for a single interface that abstracts the database engine in use (AccountDaoMySQL and AccountDaoOracle may both implement AccountDao)
A Class may implement multiple interfaces. Java does not allow multiple inheritance of concrete classes.
Abstracts implementation details. Interfaces may include only public API methods, hiding implementation details. Benefits include a cleanly documented public API and well documented contracts.
Used heavily by modern dependency injection frameworks, such as http://www.springframework.org/.
In Java, interfaces can be used to create dynamic proxies - http://java.sun.com/j2se/1.5.0/docs/api/java/lang/reflect/Proxy.html. This can be used very effectively with frameworks such as Spring to perform Aspect Oriented Programming. Aspects can add very useful functionality to Classes without directly adding java code to those classes. Examples of this functionality include logging, auditing, performance monitoring, transaction demarcation, etc. http://static.springframework.org/spring/docs/2.5.x/reference/aop.html.
Mock implementations, unit testing - When dependent classes are implementations of interfaces, mock classes can be written that also implement those interfaces. The mock classes can be used to facilitate unit testing.