类与类之间的关系详解
Java 类与类之间的关系详解
在面向对象编程中,类与类之间的关系主要分为以下6种,每种关系都有其特定的语义和实现方式:
1. 继承(Inheritance)
定义
- "is-a"关系:子类是父类的一种特殊形式
- 通过
extends
关键字实现
特点
- 子类继承父类的属性和方法
- Java 是单继承(一个类只能继承一个父类)
- 支持方法重写(Override)
代码示例
class Animal {void eat() { System.out.println("Eating..."); }
}class Dog extends Animal { // Dog is-a Animalvoid bark() { System.out.println("Barking..."); }
}
UML表示
2. 实现(Implementation)
定义
- 类与接口之间的关系
- 通过
implements
关键字实现
特点
- 一个类可以实现多个接口
- 必须实现接口中所有抽象方法(Java 8+ 允许默认方法)
代码示例
interface Swimmable {void swim();
}class Fish implements Swimmable { // Fish implements Swimmablepublic void swim() {System.out.println("Fish swimming");}
}
UML表示
3. 关联(Association)
定义
- "has-a"关系:一个类知道另一个类的存在(长期关系)
- 可以是单向或双向
类型
类型 | 描述 | 生命周期依赖 |
---|---|---|
单向关联 | A→B(A知道B,B不知道A) | 无 |
双向关联 | A↔B(互相知道) | 无 |
代码示例
class Teacher {private List<Student> students; // Teacher has Students
}class Student {private Teacher teacher; // Student has a Teacher (双向)
}
UML表示
4. 聚合(Aggregation)
定义
- 弱"has-a"关系:整体与部分可独立存在
- 通过成员变量实现,通常通过构造函数或setter注入
特点
- 部分可以属于多个整体
- 整体销毁时部分不一定销毁
代码示例
class Department {private List<Professor> professors; // Department has Professors
}class Professor { /*...*/ } // Professor可以独立存在
UML表示
5. 组合(Composition)
定义
- 强"has-a"关系:部分不能脱离整体存在
- 整体负责部分的生命周期
特点
- 部分只能属于一个整体
- 整体销毁时部分必须销毁
代码示例
class Car {private Engine engine; // Car has-an Engine (组合)public Car() {this.engine = new Engine(); // Engine随Car创建/销毁}
}class Engine { /*...*/ }
UML表示
6. 依赖(Dependency)
定义
- 临时性关系:一个类的变化可能影响另一个类
- 最弱的关系,表现为:
- 方法参数
- 局部变量
- 静态方法调用
特点
- 临时性耦合
- 不需要长期持有对象引用
代码示例
class ReportGenerator {void generate(Data data) { // 依赖Data类Formatter formatter = new Formatter(); // 依赖Formatter类// ...}
}
UML表示
关系对比总结
关系类型 | 关键词 | 生命周期 | UML箭头 | 示例 |
---|---|---|---|---|
继承 | extends | 强 | ▷ | Dog → Animal |
实现 | implements | 强 | ▷ 虚线 | Fish → Swimmable |
关联 | 成员变量 | 长期 | → | Teacher → Student |
聚合 | 成员变量 | 独立 | ◇→ | Department → Professor |
组合 | 成员变量 | 同生共死 | ◆→ | Car → Engine |
依赖 | 临时使用 | 短暂 | ⤳ 虚线 | Report ⤳ Data |
记忆技巧
“继承实现是垂直,关联聚合组合横,
依赖关系最短暂,箭头方向要分清。”
-
垂直关系(类层级):
- 继承(实线三角)
- 实现(虚线三角)
-
水平关系(对象协作):
- 关联(普通箭头)
- 聚合(空心菱形)
- 组合(实心菱形)
-
临时关系:
- 依赖(虚线箭头)
面试常见问题
-
聚合和组合有什么区别?
- 聚合:部分可独立存在(如
大学
和教师
) - 组合:部分必须随整体销毁(如
汽车
和发动机
)
- 聚合:部分可独立存在(如
-
为什么优先使用组合而不是继承?
- 组合更灵活(运行时可改变),避免继承的脆弱性
-
依赖和关联如何选择?
- 需要长期持有用关联,临时使用用依赖