前言
在面向对象中,类之间的关系有六种,分别是:
- 关联关系(Association)
- 泛化关系(Generalization)
- 依赖(Dependency)
- 聚合(Aggregation)
- 组合(Composite)
类与类之间关系
关联(Association)
两个相对独立的对象,当一个对象的实例与另一个对象的实例存在固定关系时,这两个对象之间就存在关联关系,关联体现的是一种强关联关系,关联关系形式有四种:单向关联、双向关联、自身关联和多维关联。
单向关联
场景:订单和商品,订单中包含商品,但是商品并不知道订单的存在。
UML类图:
代码体现:
C#
public class Order
{
public List<Product> products; public Order()
{
products = new List<Product>();
} public void AddProduct(Product product)
{
products.Add(product);
} public void Print()
{
foreach (var product in products)
{
Console.WriteLine(product.Name);
}
}
} public class Product
{
public string Name { get; set; }
}
JavaScript
var Order = function () {
var products = [];
this.addProduct = function (product) {
products.push(product);
}; this.Print = function () {
for (var i = 0; i < products.length; i++) {
console.log(products[i].Name);
}
}
}; var Product = function (name) {
this.Name = name;
}
双向关联
场景:订单和客户,订单属于客户,客户拥有一些订单
UML类图:
代码体现:
C#
public class Order
{
public User GetUserByOrderId(string orderId)
{
return new User();
}
}
public class User
{
public List<Order> GetOrders()
{
return new List<Order>();
}
}
JavaScript
var User = function (name) {
this.Name = name; this.getOrder = function () {
console.log("getOrder");
};
};
var Order = function () { this.getUserByOrderId = function (id) {
console.log("getUserByOrderId:" + id);
};
}
自身关联
同一个对象之间的关联
UML类图:
多维关联
多个对象之间存在联系
场景:公司雇佣员工,同时公司需要字符工资给员工
依赖(Dependency)
类A要完成某个功能必须引用类B,则A和B存在依赖关系,依赖关系是弱关联关系。
场景:司机和汽车
UML类图:
代码体现:
public class Driver
{
public void Drive(Car car)
{
car.Run();
}
} public class Car
{
public void Run()
{
Console.WriteLine("跑起来了");
}
}
JavaScript
var Driver = function () {
this.dirve = function (car) {
if (car instanceof Car) {
car.run();
} else {
throw new Error("参数异常,必须是Car类型");
}
}
}; var Car = function () {
this.run = function () {
console.log("跑起来了");
}
}
泛化(Generalization)
泛化就是类与类的的继承关系,类与接口的实现关系。
场景:狗是一个动物;鸟会飞
UML类图:
代码体现:
C#
public abstract class Animal
{ } public class Dog
{
}
JavaScript
function Animal() { } function Dog() { } Dog.prototype = new Animal();
Dog.prototype.constructor = Dog; var dog = new Dog();
console.log(dog.constructor);
console.log(dog instanceof Dog);
聚合(Aggregation)
当对象A被加入到对象B中,称为对象B的一部分时,对象A和B就存在聚合关系。聚合关系是关联关系的一种,是较强的关联关系,强调的是整体与部分之间的关系。
场景:大雁与雁群
UML类图:
代码体现
C#
public class GooseGroup
{
public Goose goose; public GooseGroup(Goose g)
{
goose = g;
} } public class Goose
{
}
JavaScript
var Goose = function() { }; var GooseGroup = function(goose) {
var _goose = goose;
console.log(_goose);
};
组合(Composition)
对象A包含对象B,对象B离开对象A就没有存在的意义,是一种更强的关联关系。
场景:大雁和翅膀
UML类图:
代码体现
C#
public class Goose
{
public Wing wing; public Goose()
{
wing = new Wing();
} } public class Wing
{
}
JavaScript
var Goose = function() { var wing = new Wing();
}; var Wing = function() {};
区别
关联和依赖区别:
- 从代码的角度看,依赖关系中依赖是作为方法的参数或返回值,或者方法的变量形式体现的;关联关系则是作为一个类的属性体现的,相比依赖,关联是更加固定,更为持久的持有的关系。
- 从生命周期来看,依赖关系则是随着类的方法被调用时而产生,伴随着方法的结束而结束;关联关系则是当类实例化的时候即产生,当类的销毁时而结束,相比依赖,关联的生命周期更长。
聚合和组合区别:
- 构造函数不同,聚合类的构造函数参数是另一个类的实例;组合类的构造函数包含另一个类的实例化。
- 信息的封装性不同,聚合关系中,GooseGroup类和Goose类是独立的,客户端都可以访问到;组合关系中,客户端只能访问到Goose类,Wing类则访问不到,因为它被封装在Goose类中。