对象组合:
正在运行的程序=对象+对象之间的合作关系
“对象组合”是对象合作关系中的一种,其含义是“一个对象包容另一个对象”。
1. “一对一”对象组合的两种类型
两种典型的对象组合方式:
方式一:A对象完全包容B对象,容器对象管理被包容对象的生命期
namespace ObjectEmbodied
{
/// <summary>
/// 被包容的对象类
/// </summary>
class InnerClass
{
}
}
/// <summary>
/// 包容方式一
/// 一般情况下,内部对象不能被外界直接访问
/// (当然,根据需要也可以设为Public的)
/// 要在包容类的构造函数中创建被包容对象
/// 如果此种对象仅在本类中使用,还可以把其类的定义为内部类
/// </summary>
class OneToOneClass
{
private InnerClass obj;
public OneToOneClass()
{
obj = new InnerClass();
}
}
方式二:B对象是独立的,A对象引用现成的B对象
/// <summary>
/// 包容方式二
/// 包容的对象由外界负责创建,通常采用对象注入的方式
/// </summary>
class OneToOneClass2
{
private InnerClass obj = null;
public OneToOneClass2(InnerClass outerObj)
{
this.obj = outerObj;
}
}
测试:
private static void One2OneTest()
{
//创建第一种包容方式的对象
//其内部已自动创建好包容的B对象
//但外界不能直接访问
OneToOneClass obj = new OneToOneClass();
//使用第一种包容方式的对象
//……
//当obj所引用的对象被销毁时,其内部对象也同时被销毁
//实现第二种对象组合方式
OneToOneClass2 container = new OneToOneClass2(new InnerClass());
//使用第二种包容方式的对象
//……
//container和obj所引用的对象其生命周期是相互独立的,
//一个对象被销毁不会自动导致另一个对象也被销毁
}
2. “一对多”的对象组合方式
• 使用集合类型(比如数组,List<T>之类) 的内部字段,很容易实现一对多的对象组合方式
方式一:A对象完全包容多个B对象
举例:一辆车有多个车轮
/// <summary>
/// 一对多的对象组合方式一
/// 通常会定义一些公有方法实现向其内部集合中增删对象
/// </summary>
class OneToManyClass
{
/// <summary>
/// 内部对象集合
/// </summary>
private List<InnerClass> objs=new List<InnerClass>();
public void Add(InnerClass obj)
{
if (obj != null)
{
objs.Add(obj);
}
}
public void Remove(int index)
{
if (index >= 0 && index < objs.Count)
{
objs.RemoveAt(index);
}
}
}
方式二:B对象是独立的
举例:停车场停了很多辆车
/// <summary>
/// 一对多的对象组合方式二
/// 一般使用对象注入的方式关联上外部对象集合
/// 对象集合放在外部,本身通常不需要提供向此对象集合中增删对象的方法
/// </summary>
/// <typeparam name="T"></typeparam>
class OneToManyClass2<T>
{
/// <summary>
/// 内部对象集合
/// </summary>
private IEnumerable<T> objs = null;
public OneToManyClass2(IEnumerable<T> objCollections)
{
objs = objCollections;
}
}
测试:
private static void One2ManyTest()
{
OneToManyClass outer = new OneToManyClass();
//添加5个对象
for (int i = 0; i < 5; i++)
{
outer.Add(new InnerClass());
}
//移除第1个对象
outer.Remove(0);
List<InnerClass> innerObjs = new List<InnerClass>();
//添加5个对象
for (int i = 0; i < 5; i++)
{
innerObjs.Add(new InnerClass());
}
OneToManyClass2<InnerClass> outer2 = new OneToManyClass2<InnerClass>(innerObjs);
}
3. 对象组合的特殊形式——自引用类
class MyClass
{
MyClass obj;
}
使用自引用类实现链表
//链表节点
class LinkNode
{
public Object Data; //数据域
public LinkNode Next = null; //指针域
}
测试:
static void Main(string[] args)
{
//生成链表节点
LinkNode Head = new LinkNode(){ Data="Head"};
LinkNode First = new LinkNode() { Data = "First" };
LinkNode Second = new LinkNode() { Data = "Second" };
LinkNode Tail = new LinkNode() { Data = "Tail" };
//建立链表
Head.Next = First;
First.Next = Second;
Second.Next = Tail;
//访问链表的全部节点
LinkNode node;
node = Head;
while (node != null)
{
//从node.Data中取出节点数据,干一些事
if(node.Next!=null)
Console.Write("{0}-->", node.Data);
else
Console.Write("{0}", node.Data);
node = node.Next;//移往下一个节点
}
Console.ReadKey();
}
在没有指针的面向对象编程语言中,自引用类可用于代替指针建立数据之间的关联。