您好,登录后才能下订单哦!
# 为什么Java中的Collection类都继承了抽象类还要实现抽象类的接口
## 引言
在Java集合框架中,我们经常会看到类似这样的继承结构:`ArrayList`继承自`AbstractList`,同时又实现了`List`接口。这种"既继承抽象类又实现接口"的设计模式看似冗余,实则蕴含了Java集合框架的精妙设计思想。本文将深入探讨这种设计背后的原因。
## 一、Java集合框架的基本结构
Java集合框架主要分为两大类:
1. **Collection接口**:代表一组对象的容器
- List(有序可重复)
- Set(无序不可重复)
- Queue(队列)
2. **Map接口**:键值对映射
以List体系为例,典型继承关系如下:
Iterable (接口) ↑ Collection (接口) ↑ List (接口) ↑ AbstractList (抽象类) ↑ ArrayList (具体类)
## 二、接口与抽象类的分工
### 1. 接口的作用
- **定义契约**:`List`接口声明了所有列表必须实现的方法(如`add()`, `get()`)
- **多态支持**:允许通过接口类型引用不同实现
- **解耦**:使用者只需依赖接口,不关心具体实现
### 2. 抽象类的作用
- **代码复用**:`AbstractList`提供了通用方法的默认实现
- **骨架实现**:定义了基本结构,减少子类工作量
- **部分实现**:可以只实现部分方法,将核心方法留给子类
## 三、为什么要同时使用两者?
### 1. 设计模式的应用
这种设计是**模板方法模式**的典型应用:
- 接口定义"做什么"
- 抽象类定义"怎么做"的基本流程
- 具体类实现特定行为
```java
// 模板方法示例
public abstract class AbstractList {
// 模板方法
public boolean addAll(Collection c) {
// 通用流程...
for (Object o : c) {
add(o); // 调用抽象方法
}
// 通用流程...
}
public abstract boolean add(Object o);
}
Java集合框架在1.2版本引入时,需要兼容旧的Vector
和Hashtable
等类。抽象类作为适配层帮助平滑过渡。
public class ArrayList extends AbstractList
implements List, RandomAccess,
Cloneable, Serializable
RandomAccess
:标记支持快速随机访问Cloneable
:支持克隆Serializable
:支持序列化假设只有抽象类: - 所有实现必须继承同一父类,失去灵活性 - Java不支持多继承,无法扩展其他功能
假设只有接口: - 每个实现类都要重复编写通用代码 - 增加维护成本
CollectionBase
/DictionaryBase
面向接口编程:变量声明尽量使用接口类型
// 推荐
List list = new ArrayList();
// 不推荐
ArrayList list = new ArrayList();
合理使用抽象类:
接口演化原则:
Java集合框架通过接口与抽象类的组合设计,实现了: - 规范统一(接口) - 代码复用(抽象类) - 灵活扩展(组合使用) - 兼容过渡(历史原因)
这种设计体现了”针对接口编程”和”不要重复自己(DRY)“的原则,是Java优秀API设计的典范。理解这一设计思想,有助于我们编写更优雅、可维护的代码。
“Program to an interface, not an implementation.” —《Design Patterns》Gang of Four “`
这篇文章共计约1150字,采用Markdown格式,包含: 1. 多级标题结构 2. 代码块示例 3. 列表和对比表格 4. 引用和总结 5. 技术术语解释 6. 实际案例和设计模式分析
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。