所有 Collections 都实现接口Collection,这些集合具有特定的抽象层次结构,例如
但也有对应的接口,如Collection、List、Set。这些界面在我看来有点多余。
他们为什么在这里?这只是约定,或者是否有理由只实现接口而不扩展抽象类。
所有 Collections 都实现接口Collection,这些集合具有特定的抽象层次结构,例如
但也有对应的接口,如Collection、List、Set。这些界面在我看来有点多余。
他们为什么在这里?这只是约定,或者是否有理由只实现接口而不扩展抽象类。
接口之所以存在,是因为能够在不强制实现的情况下将类型分配给变量或参数是很好的。
例如,如果我创建了一个在 Hibernate 中使用的持久实体,并且它有一个集合,我想为其分配一个 List 或 Set 类型。Hibernate 将用它自己的列表替换我初始化它的任何列表,并使用一些特定于 Hibernate 的实现来执行延迟加载或其他任何它需要的实现。Hibernate 开发人员可能不希望受到必须扩展抽象类的限制。
抽象类的存在是为了方便实现者。接口是客户端使用的合约。
实现接口与扩展抽象类有很大不同。
让我们假设 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()
为什么不 ?抽象类是为了简化继承过程。当您想创建您的收藏时,您不必从头开始做所有事情。
但是当然没有人告诉你应该从 AbstractCollection 继承。您可以从头开始编写实现。
这是 API 具有接口的常见良好做法。并区分实现和接口。
接口是用户和实现者之间的契约。抽象基类旨在用作访问许多行为相似的对象的公共基础。