سی شارپ - کلاس ها

زمانی که یک کلاس تعریف می کنید، در واقع یک طرح کلی برای نوع داده تعریف می کنید. درواقع هیچ داده ای در اینجا تعریف نمی شود، اما مشخص می کند نام کلاس به چه معناست، که عبارت است از یک شی از کلاس شامل چه چیز خواهد بود و چه عملیاتی می توان روی چنین شی یی انجام داد. شی ها نمونه هایی از کلاس ها هستند. متدها و متغیرهایی که یک کلاس را تشکیل می دهند اعضای آن کلاس نامیده می شوند.

تعریف یک کلاس

تعریف کلاس با کلمه ی کلیدی class شروع می شود و نام آن کلاس و بدنه ی کلاس که در یک جفت آکولاد قرار دارد، به دنبان آن می آید و در زیر یک فرم کلی از تعریف یک کلاس نشان داده شده است.

<access specifier> class  class_name
{
   // member variables
   <access specifier> <data type> variable1;
   <access specifier> <data type> variable2;
   ...
   <access specifier> <data type> variableN;
   // member methods
   <access specifier> <return type> method1(parameter_list)
   {
      // method body
   }
   <access specifier> <return type> method2(parameter_list)
   {
      // method body
   }
   ...
   <access specifier> <return type> methodN(parameter_list)
   {
      // method body
   }
}

نکته

  • Access specifiers قوانین دسترسی را برای اعضا و همچنین برای خود کلاس مشخص می کند، که اگر ذکر نشده باشد access specifier پیش فرض برای یک کلاس internal. و دسترسی پیش فرض برای اعضا private . خواهد بود
  • نوع داده نوع متغیر را تعریف می کند و برای دسترسی به اعضای کلاس از عملگر دات (.) استفاده می شود.
  • عملگر نقطه یا دات، نام یک شی را به نام یک عضو وصل می کند.

در مثال زیر مفاهیم توضیح داده شده در بالا ، نشان داده شده است

using System;
namespace BoxApplication
{
    class Box
    {
       public double length;   // Length of a box
       public double breadth;  // Breadth of a box
       public double height;   // Height of a box
    }
    class Boxtester
    {
        static void Main(string[] args)
        {
            Box Box1 = new Box();   // Declare Box1 of type Box
            Box Box2 = new Box();   // Declare Box2 of type Box
            double volume = 0.0;    // Store the volume of a box here

            // box 1 specification
            Box1.height = 5.0;
            Box1.length = 6.0;
            Box1.breadth = 7.0;

            // box 2 specification
            Box2.height = 10.0;
            Box2.length = 12.0;
            Box2.breadth = 13.0;
           
            // volume of box 1
            volume = Box1.height * Box1.length * Box1.breadth;
            Console.WriteLine("Volume of Box1 : {0}",  volume);

            // volume of box 2
            volume = Box2.height * Box2.length * Box2.breadth;
            Console.WriteLine("Volume of Box2 : {0}", volume);
            Console.ReadKey();
        }
    }
}

نتیجه ی اجرای دستورات بالا به شکل زیر است.

Volume of Box1 : 210
Volume of Box2 : 1560

توابع عضو و کپسوله سازی یا Encapsulation

تابع عضو از یک کلاس تابعی است که در آن کلاس تعریف شده و یا نمونه ی اولیه ی آن در آن کلاس قرار دارد، مانند هر متغیر دیگری. و روی هریک از اشیا عضو آن کلاس عملیاتی را انجام می دهد و به همه ی اعضای آن کلاس برای آن شی دسترسی دارد.

متغیرهای عضو، ویژگی های یک شی می باشند که به طور private تعریف می شوند تا encapsulation را پیاده سازی کنند. این متغیرها تنها از طریق توابع عضو عمومی قابل دسترسی هستند.

اجازه بدهید مفاهیم بالا را جهت ارسال و دریافت مقادیر اعضا ی یک کلاس ، در یک کلاس دیگر نشان بدهیم

using System;
namespace BoxApplication
{
   class Box
   {
      private double length;   // Length of a box
      private double breadth;  // Breadth of a box
      private double height;   // Height of a box
      public void setLength( double len )
      {
         length = len;
      }
      
      public void setBreadth( double bre )
      {
         breadth = bre;
      }
      
      public void setHeight( double hei )
      {
         height = hei;
      }
      public double getVolume()
      {
         return length * breadth * height;
      }
   }
   class Boxtester
   {
      static void Main(string[] args)
      {
         Box Box1 = new Box();   // Declare Box1 of type Box
         Box Box2 = new Box();
         double volume;
         
         // Declare Box2 of type Box
         // box 1 specification
         Box1.setLength(6.0);
         Box1.setBreadth(7.0);
         Box1.setHeight(5.0);
         
         // box 2 specification
         Box2.setLength(12.0);
         Box2.setBreadth(13.0);
         Box2.setHeight(10.0);
         
         // volume of box 1
         volume = Box1.getVolume();
         Console.WriteLine("Volume of Box1 : {0}" ,volume);
         
         // volume of box 2
         volume = Box2.getVolume();
         Console.WriteLine("Volume of Box2 : {0}", volume);
         
         Console.ReadKey();
      }
   }
}

نتیجه ی اجرای دستورات بالا به شکل زیر است

Volume of Box1 : 210
Volume of Box2 : 1560

سازنده های سی شارپ

سازنده ی یک کلاس تابع عضو خاصی از یک کلاس می باشد که هر زمان که شی جدیدی از آن کلاس را ایجا کنیم اجرا می شود.

یک سازنده دقیقا نام کلاس را دارد و هیچ گونه نوع بازگشتی ندارد. مثال زیر مفهوم سازنده را توضیح می دهد.

using System;
namespace LineApplication
{
   class Line
   {
      private double length;   // Length of a line
      public Line()
      {
         Console.WriteLine("Object is being created");
      }

      public void setLength( double len )
      {
         length = len;
      }
      
      public double getLength()
      {
         return length;
      }

      static void Main(string[] args)
      {
         Line line = new Line();    
         
         // set line length
         line.setLength(6.0);
         Console.WriteLine("Length of line : {0}", line.getLength());
         Console.ReadKey();
      }
   }
}

نتیجه ی اجرای دستورات بالا به صورت زیر است

Object is being created
Length of line : 6

یک سازنده ی پیش فرض هیچ پارامتری ندارد، امااگر شما به دادن پارامتر به آن نیاز دارید یک سازنده می تواند پارامتر بگیرد، چنین سازنده هایی سازنده های parameterized نامیده می شوند. این تکنیک به شما کمک می کند تا یک مقدار اولیه به یک شی در زمان ایجاد آن، اختصاص دهید، این عملکرد در مثال زیر نشان داده شده است.

using System;
namespace LineApplication
{
   class Line
   {
      private double length;   // Length of a line
      public Line(double len)  //Parameterized constructor
      {
         Console.WriteLine("Object is being created, length = {0}", len);
         length = len;
      }

      public void setLength( double len )
      {
         length = len;
      }
      public double getLength()
      {
         return length;
      }

      static void Main(string[] args)
      {
         Line line = new Line(10.0);
         Console.WriteLine("Length of line : {0}", line.getLength()); 
         
         // set line length
         line.setLength(6.0);
         Console.WriteLine("Length of line : {0}", line.getLength()); 
         Console.ReadKey();
      }
   }
}

نتیجه ی اجرای قطعه کد بالا به صورت زیر است

Object is being created, length = 10
Length of line : 10
Length of line : 6

تخریب کننده ها (destructors) در C#

Destructor یک تابع خاص از اعضای کلاس می باشد که هروقت یک شی ازمحدوده خارج شود، این عملکرد اجرا می شود. تخریب کننده دقیقا همان نام کلاس را دارد که با این نشان (~) پیشوند دار شده است که نه می تواند مقداری را برگردانده و نه هیچ پارامتری بگیرد.

تخریب کننده می تواند برای آزاد کردن منابع قبل از خروج برنامه خیلی مفید باشد،مانند بستن فایل ها، آزاد کردن حافظه و غیره. تخریب کننده ها نمی توانند ارث بری شده و یا overload شود

در مثال زیر نحوه کار تخریب کننده توضیح داده شده است

using System;
namespace LineApplication
{
   class Line
   {
      private double length;   // Length of a line
      public Line()  // constructor
      {
         Console.WriteLine("Object is being created");
      }
      ~Line() //destructor
      {
         Console.WriteLine("Object is being deleted");
      }

      public void setLength( double len )
      {
         length = len;
      }
      
      public double getLength()
      {
         return length;
      }

      static void Main(string[] args)
      {
         Line line = new Line();
         
         // set line length
         line.setLength(6.0);
         Console.WriteLine("Length of line : {0}", line.getLength());           
      }
   }
}

نتیجه ی اجرای کدهای بالا به صورت زیر است

Object is being created
Length of line : 6
Object is being deleted

اعضای استاتیک یک کلاس C#

با استفاده از کلمه ی کلیدی static می توان اعضای کلاس را به عنوان استاتیک تعریف کرد. وقتی که عضوی از یک کلاس را به عنوان استاتیک معرفی می کنیم به این معناست که مهم نیست چه تعداد شی از یک کلاس استفاده می شودد، تنها یک کپی از عضو استاتیک وجود دارد

کلمه ی کلیدی static به این معناست که تنها یک نمونه برای یک کلاس وجود دارد. متغیرهای استاتیک برای تعریف ثابت ها به کار می روند، زیرا مقادیر آنها هنگام استفاده از یک کلاس و بدون ایجاد نمونه ای از آن قابل دسترسی می باشد. متغیرهای استاتیک می توانند بیرون از تابع عضو یا تعریف کلاس ، مقداردهی اولیه شوند. شما همچنین می توانید مقداردهی اولیه ی متغیرهای استاتیک را در تعریف کلاس انجام دهید .

در کد زیر نحوه ی استفاده از متغیر های استاتیک توضیح داده شده است

using System;
namespace StaticVarApplication
{
   class StaticVar
   {
      public static int num;
      public void count()
      {
         num++;
      }
      public int getNum()
      {
         return num;
      }
   }
   class StaticTester
   {
      static void Main(string[] args)
      {
         StaticVar s1 = new StaticVar();
         StaticVar s2 = new StaticVar();
         s1.count();
         s1.count();
         s1.count();
         s2.count();
         s2.count();
         s2.count();
         Console.WriteLine("Variable num for s1: {0}", s1.getNum());
         Console.WriteLine("Variable num for s2: {0}", s2.getNum());
         Console.ReadKey();
      }
   }
}

نتیجه ی اجرای دستورات بالا به صورت زیر است

Variable num for s1: 6
Variable num for s2: 6

شما همینطور می توانید توابع عضو کلاس را نیز به صورت استاتیک تعریف کنید.این توابع فقط می توانند به متغیر های استاتیک دسترسی داشته باشند.این توابع استاتیک قبل از اینکه شی کلاس ساخته شود وجود دارند.در مثال زیر توابع استاتیک توضیح داده شده اند

using System;
namespace StaticVarApplication
{
   class StaticVar
   {
      public static int num;
      public void count()
      {
         num++;
      }
      public static int getNum()
      {
         return num;
      }
   }
   class StaticTester
   {
      static void Main(string[] args)
      {
         StaticVar s = new StaticVar();
         s.count();
         s.count();
         s.count();
         Console.WriteLine("Variable num: {0}", StaticVar.getNum());
         Console.ReadKey();
      }
   }
}

نتیجه ای اجرای دستورات بالا به صورت زیر خواهد بود

Variable num: 3