关联用来表示两个或多个类的对象之间的结构关系,它在代码中表现为一个类以属性的形式包含对另一个类的一个或多个对象的应用。
假设:一个公司只有三名员工:一个员工要么没有工作,要么只能在一个公司工作。(代码简化了,主要说明关联关系)
Person类
class person{ public string name; public person(string eName){ name = eName; } public void startWork(){ Console.WriteLine("员工{0}开始工作",name); } }
Company类
class company{ public string name;//公司名称 public person[ ] employee = new person[3]; public company(string cName){ name = cName; } public void run(){ Console.WriteLine("公司“{0}”开始运作",name); employee[0].startWork(); employee[1].startWork(); employee[2].startWork(); } public void stop(){ Console.WriteLine("公司“{0}”停止运作", name); } } //控制台 class Program{ static void Main(string[] args) { company c = new company("北京能力有限公司"); c.employee[0] = new person("张三"); c.employee[1] = new person("李四"); c.employee[2] = new person("王二"); c.run(); c.stop(); Console.Read(); } }
输出
对应的类图
概念:两个类之间的关联成为二元关联。
符号:
比如:在一个大公司里,公司总裁只认识那些核心职员,不认识所有的普通职员,而所有的职员都认识总裁。
public class 大公司总裁{ private 核心职员 A; } public class 核心职员{ private 大公司总裁 B; } public class 普通职员{ private 大公司总裁 B; }
对应的类图
单向关联关系对应的代码:
public class A{ private B b; } public class B{ }
双向关联关系对应的代码:
public class A{ private B b; } public class B{ private A a; }
关联的名称表达了关联的内容,一般使用动宾结构的短语。(例如上面的类图中:work)
关联命名的原则是该命名是否有助于理解该模型。
关联中的角色是类的对象在关联中所扮演的角色。例如上图中的:employer(雇佣方),employee(员工:受雇佣的人)。关联的角色会转换为代码。
class company{ public string name; //公司名称 public person[ ] employee = new person[3]; public company(string cName){ name = cName; } …… }
class company{ public string name; //公司名称 // "+" public person[] employee = new person[3]; public company(string cName){ name = cName; } …… }
多重性是指有多少个对象参与了关联。具体的说,是指类A的一个对象对应类B的对象的个数。如下:
public class 狗 { private 腿[] X = new 腿[4]; } public class 腿 { …… }
1: 表示1个
0..*: 表示任意多个( ≥0)(*可以换成n)
*: 表示任意多个( ≥0)
1..*: 表示1个或多个(≥1)
0..1: 表示0个或1个
5..11: 表示5-11个
1,3,8: 表示个1或3个或8个
0,3..8: 表示0个或3-8个
聚合(聚集)与组合(合成、组成)是两种特殊的关联。
一、聚合(关联的特例)
聚合的概念:聚合表示类之间的整体与部分的关系。聚合意味着一个类拥有但共享另一个类的对象。
程序演示:聚合(code/associationB)
class cpu{ public string name; //品牌 public string rate; //主频 public cpu(string cpuName,string cpuRate){ name = cpuName; rate = cpuRate; } } class computer{ public string buyTime; public string color; public cpu mycpu; public computer(string computerBuyTime,string computerColor){ buyTime = computerBuyTime; color = computerColor; } public void cpuInfo(){ Console.WriteLine("该电脑的CPU品牌为:{0}",mycpu.name); Console.WriteLine("该电脑的CPU主频为:{0}", mycpu.rate); } } class Program{ static void Main(string[ ] args){ cpu cpuA = new cpu("Intel","2.93"); cpu cpuB = new cpu("AMD","2.61"); computer computerC = new computer("2008-9-1","黑色"); Console.WriteLine("购买时间为:{0}", computerC.buyTime); Console.WriteLine("颜色为:{0}\n", computerC.color); Console.WriteLine("现在安装第一块CPU"); computerC.mycpu = cpuA; //将cpuA装入该电脑中 computerC.cpuInfo(); Console.WriteLine("\n现在安装第二块CPU"); computerC.mycpu = cpuB; //将cpuA装入该电脑中 computerC.cpuInfo(); } }
聚合的符号,在整体类端加空心菱形。
当整体类不存在时,不分类仍可能存在。部分类销毁时,整体类也将能够存在。关联关系和聚合关系在语法上是没办法区分的,得从语义上才能更好的区分两者的区别。
二、组成
组成的概念:组成是一种特殊形式的聚合。
与聚合相比,它有两个特点:
一个部分类最多只能属于一个整体类
当整体类不存在时,部分类将同时被销毁。
最容易理解的一个例子就是窗体和文本框,当窗体不存在时,文本框也将不存在。
组成的符号:
在整体类端加实心菱形。如图:
关联关系所涉及的两个类是处于同一个层次上的。比如学生和课程就是一种关联关系,而不是聚合关系,因为学生不是有课程组成的。
聚合关系涉及的两个类处于不平等的层次上,一个代表整体,一个代表部分。比如电脑和显示器、键盘、主板、内存就是聚合关系,因为主板是电脑的组成部分。而键盘等部件不会因为电脑没了,就不存在了。
聚合与组合的区别:
组合:整体类端的重数必须是1,部分类的重数是任意的。
聚合:整体类端的重数可以大于1,部分类的重数是任意的。