所有集合实现接口Collection,这些集合具有特定的抽象层次结构,例如
但也有相应的界面,如Collection,List,Set。这些界面在我看来是多余的。
为什么他们在这里?是仅仅是约定还是有理由只实现接口而不扩展抽象类。
答案 0 :(得分:7)
接口是存在的,因为能够在不强加实现的情况下将类型分配给变量或参数是很好的。
例如,如果我创建一个在Hibernate中使用的持久化实体,并且它有一组东西,我想为它分配一种List或Set类型。 Hibernate会将我初始化它的任何列表换成自己的,使用一些特定于Hibernate的实现来执行延迟加载或其他任何需要它的东西。 Hibernate开发人员可能不希望因为必须扩展抽象类而受到限制。
抽象类的存在是为了实现者的便利。界面是客户使用的合同。
答案 1 :(得分:1)
实现接口与扩展抽象类有很大不同。
让我们假设Animal类是一个抽象类,Dog,Cat,Snake和Shark扩展Animal。
默认的Animal.move()实现只是移动它们。
但是,接口允许我们进一步分组出类似的动物,例如RunningAnimal,SwimmingAnimal。
因此,如果Dog扩展Animal实现了RunningAnimal,那么沿着继承的move(),他还必须实现自己的run(),这可能会在从Animal继承的重写的move()中找到它。这对你有意义还是我需要更好地澄清一些代码? :)
接口允许您对不同类的类似功能进行分组。 “可点击”,“可排序”,“可序列化”......它们都通过共享功能包含成员(因此可点击列表不仅仅是按钮列表)而不是相同的目的。
所以,想想就像这样
Cat extends Animal implements RunningAnimal, ClimbingAnimal -- inherits move() has to implement run() and climbTree()
Dog extends Animal implements RunningAnimal -- inherits move(), has to implement run()
Snake extends Animal -- likely overrides inherited move()
Shark extends Animal implements SwimmingAnimal -- likely overrides move(), has to implement swim()
答案 2 :(得分:1)
为什么不呢?抽象类用于简化继承过程。当您想要创建集合时,您不必从头开始做任何事情。
但当然没有人告诉你,你应该继承自AbstractCollection。您可以从头开始编写实现。
这是API拥有接口的常见做法。并区分实现和接口。
答案 3 :(得分:1)
接口是用户和实施者之间签订的合同。抽象基类旨在用作访问许多类似行为对象的公共基础。