ترکیب (Containment)

محدود نگه داشتن یا ترکیب فرایندی است که طی آن یک کلاس به عنوان یک عضو به کلاس دیگر اضافه می‌شود. به عنوان مثال کلاس Person می‌تواند یک فیلد از نوع کلاس Name داشته باشد. به کد زیر توجه کنید :

   1: using System;                                                  
   2:                                                                
   3: class Name                                                     
   4: {                                                              
   5:     public string FirstName { get; set; }                      
   6:     public string LastName { get; set; }                       
   7:                                                                
   8:     public Name(string f, string l)                            
   9:     {                                                          
  10:         FirstName = f;                                         
  11:         LastName = l;                                          
  12:     }                                                          
  13: }                                                              
  14:                                                                
  15: class Person                                                   
  16: {                                                              
  17:     private Name myName;                                       
  18:                                                                
  19:     public Name MyName                                         
  20:     {                                                          
  21:         get { return myName; }                                 
  22:         set { myName = value; }                                
  23:     }                                                          
  24:                                                                
  25:     public Person(Name name)                                   
  26:     {                                                          
  27:         myName = new Name(name.FirstName, name.LastName);      
  28:     }                                                          
  29:                                                                
  30:     public override string ToString()                          
  31:     {                                                          
  32:         return myName.FirstName + " " + myName.LastName;       
  33:     }                                                          
  34: }                                                              
  35:                                                                
  36: class Program                                                  
  37: {                                                              
  38:     public static void Main()                                  
  39:     {                                                          
  40:         Person person1 = new Person(new Name("John", "Smith"));
  41:                                                                
  42:         Console.WriteLine(person1.ToString());                 
  43:     }                                                          
  44: }
John Smith

حال برنامه را به صورت بخش بخش توضیح می‌دهیم :

class Name
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public Name(string f, string l)
    {
        FirstName = f;
        LastName = l;
    }
}

یک کلاس که قرار است به عنوان یک فیلد در کلاس دیگر به کار رود را تعریف می‌کنیم (خط 17). این کلاس، دارای یک سازنده است که نام (f) و نام خانوادگی (l) را از شخص دریافت می‌کند. سپس این مقادیر را در خصوصیت‌های متناظر با آنها قرار می‌دهیم (خطوط 12-5).

class Person
{
    private Name myName;

    public Name MyName
    {
        get { return myName; }
        set { myName = value; }
    }

    public Person(Name name)
    {
        myName = new Name(name.FirstName, name.LastName);
    }

    public override string ToString()
    {
        return myName.FirstName + " " + myName.LastName;
    }
}

این کلاس شامل یک فیلد از نوع Name و خاصیت متناضر با آن است. این خصوصیت مقدار نام هر شی Person را در خود نگهداری می‌کند. به این نکته توجه کنید که سازنده یک شیء Name را می‌پذیرد و سپس با استفاده از این شیء فیلد myName را مقداردهی می‌کند. به این فرایند ترکیب (aggregation) می گویند.
همچنین در کلاس Person متد ToString() از کلاس System.Object را بازنویسی (override) می‌کنیم به طوری که در هنگام فراخوانی نام کامل شخص را نمایش دهد.

class Program
{
    public static void Main()
    {
        Person person1 = new Person(new Name("John", "Smith"));

        Console.WriteLine(person1.ToString());
    }
}

در بالا یک شیء Person را ایجاد و از سازنده‌ای که یک شیء از نوع کلاس Name به عنوان آرگومان قبول می‌کند استفاده کرده‌ایم. این شیء را مستقیماً در داخل پرانتزها تعریف و همچنین مقادیر خصوصیات firstname و lastname را به آن ارسال کرده‌ایم. در نهایت، با استفاده از متد سفارشی ToString() نتیجه را چاپ می‌کنیم. به این نکته توجه کنید که کلاس‌ها می‌توانند اشیایی از نوع خود کلاس داشته باشند. به عنوان نمونه کلاس Person می‌تواند یک عضو با نوع Person داشته باشد. به کد زیر توجه نمایید :

class Person
{
   public Person Sibling { get; set; }
   public string Name { get; set; }
}

مشاهده می‌کنید که چگونه خصوصیتی از نوع Person در داخل کلاس Person تعریف شده است. پس هنگامی که یک شیء Person تعریف می‌کنید، شیء ایجاد شده یک شیء از نوع Person در داخل خود دارد.

Person person1 = new Person();
person1.Sibling = new Person();
person1.Name = "John Smith";
person1.Sibling.Name = "Mike Smith";

کد بالا چگونگی دسترسی و مقدار دهی به عضو (Sibling)Person را نشان داده است. از آنجایی که خصوصیت Sibling از نوع Person است پس می‌تواند یک شیء Person در داخل خود داشته باشد. بنابراین می‌توان هر تعداد sibling که می‌خواهید در داخل شیء person1 داشته باشید :

person1.Sibling.Sibling = new Person();
person1.Sibling.Sibling.Name = "Franc Smith";
person1.Sibling.Sibling.Sibling = new Person();
person1.Sibling.Sibling.Sibling.Name = "Bob Smith";
//And so on...