معرفی شی گرایی در #C

در این مقاله شما اصول اولیه شی گرایی در # c را خواهید آموخت . برنامه نویسی شی گرا یا object oriented programing که به صورت oop هم نوشته می شود . یک الگوی برنامه نویسی است .در برنامه نویسی شی گرا (oop) بخش های برنامه نویسی به صورت شی هایی در نظر گرفته می شود که باهم در ارتباط هستند ودر این رابطه اقدام به تعریف کلاس هایی می کنند که اشیا بر مبنای آن تعریف می شود.

معرفی شی گرایی در #C

برنامه نویسی شی گرایی (oop) در هر زبانی بخش بسیار مهمی می باشد. در حال حاضر اینجا برخی از اطلاعات در مورد شی گرایی گفته شده است. 

(کلاس)Class :

- یک کلاس نوعی از مجموعه اشیاست.

- یک کلاس قابل تعریف توسط کاربر می باشد. یک کلاس باید دارای یک اسم باشد.

- نام یک کلاس یک کلمه می باشد به عنوان مثال: کارمند ، مشتری، ماشین و غیره و اولین حرف باید به صورت بزرگ باشد.

- یک کلاس با پسوندcs . در #C ذخیره میشود.

- یک کلاس مهم ترین بخش از شی گرایی می باشد.

- یک کلاس توسط یک کلید واژه شناسایی می شود.

مثال :

1.	namespace OPPS  
2.	{  
3.	   class OppsDemo  
4.	   {  
5.	      static void Main(string[] args)  
6.	      {  
7.	         // declare variable, method   
8.	      }  
9.	   }  
10.	}  

 

 

(شی) Object :

اشیا در کلاس ها استفاده می شوند، در اینجا یک متغیر اعلان می شود که بر ایجاد یک شی یا نمونه ای از کلاس اشاره دارد.یک متغیر توسط کلیدواژه var شناسایی می شود.

به مثال زیر توجه کنید :

1.	class OppsDemo  
2.	{  
3.	   static void Main(string[] args)  
4.	   {  
5.	      Demo d = new Demo();  
6.	  
7.	   }  
8.	}  

نکته : کلاس ایجاد شده در هر پروژه جاری قابل دسترس می باشد.

همچنین یک شی Null در یک کلاس می شود ایجاد کرد.

1.	Demo d = null;  

در اینجا می توان کلید واژه جدیدی برای garbage collection مشاهده کرد. به عبارت دیگر وقتی ما استفاده ی کلید واژه جدیدی را شناسایی می کنیم شما فضایی برای متغیر جدید ایجاد می کنید. Garbage Collection به صورت اتوماتیک ارزش متغیر را در NETFramework. پاکسازی می کند.  

در حال حاضر همان طور که در ادامه می بینید در کلاس Employee متغیری را شناسایی می کنیم:

    class Employee  
    {  
       static void Main(string[] args)  
       {  
      
          string Name;  
          int Age;  
       }  
    }  

یک مثال برای کلاس در زیر مشاهده نمایید :

خروجی :

(متد) Method :

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

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

    void Display()  
    {  
      
    }  

همچنین مفهوم استفاده از سطح دسترسی  به صورت عمومی ، خصوصی و یا داخلی می باشد .

حالا اینجا نمونه ای از فراخوانی متد را مشاهده می کنیم :

1.	namespace OPPS   
2.	{   
3.	    public class Addition   
4.	    {   
5.	       public int count(int a, int b)   
6.	       {   
7.	           int c;   
8.	   
9.	           c = a + b;   
10.	   
11.	           return c;   
12.	       }   
13.	       static void Main(string[] args)   
14.	        {   
15.	            int a = 10;   
16.	            int b = 5;   
17.	            int Result;   
18.	   
19.	            Addition add = new Addition();   
20.	           //call method   
21.	            Result = add.count(a, b);   
22.	            Console.WriteLine("Addition Count:{0}",Result);   
23.	            Console.ReadLine();   
24.	              
25.	        }   
26.	    }   
27.	}  

 

خروجی:

 

مقداری اطلاعات در مورد یک نوع متد کسب میکنیم :

1. ارسال از طریق مقدار(pass by value)

2. ارسال از طریق رفرنس (Pass by References)

- ارسال از طریق مقدار

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

    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Text;  
      
    namespace OPPS  
    {  
        public class PersonInfo  
        {  
           private void Info (string Name, string city)  
           {  
               Console.WriteLine("Person Information:");  
               Console.WriteLine("------------------------------------");  
               Console.WriteLine("Person Name:");  
               Console.WriteLine(Name);  
               Console.WriteLine("------------------------------------");  
               Console.WriteLine("Person City:");  
               Console.WriteLine(city);  
           }  
           static void Main(string[] args)  
            {  
                PersonInfo P_Info = new PersonInfo();  
      
                string Name = "Rakesh Chavda";  
                string city = "Ahmedabad";  
      
                P_Info.Info(Name, city);  
                 
               Console.ReadLine();  
                 
            }  
        }  
    }  

خروجی :

در این مثال دو نمونه از متد استاتیک را مشاهده می کنید. اولی نقطه ورود در برنامه و دیگری اطلاعات می باشد که دارای دو پارامتر نام و شهر می باشد . در این متد بعد از نمایش مقدار ذخیره می شود.

        2.ارسال از طریق Refrence :

         در این متد ارسال به متغیر توسط refrence را مشاهده می کنید.

    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Text;  
      
    namespace OPPS  
    {  
        class Info  
        {  
            public string Name;  
            public string city;  
        }  
      
        public class PersonInfo  
        {  
            static void Main(string[] args)  
            {  
                Info i = new Info();  
      
                i.Name = "Rakesh";  
                i.city = "Ahmedabad";  
      
                Console.WriteLine("Person Name: {0}",i.Name);  
                Console.WriteLine("Person City: {0}",i.city);  
                 
               Console.ReadLine();  
                 
            }  
        }  
    }  

 

خروجی :

     اینجا اطلاعات کلاس را به صورت رشته ای به عنوان public در نظر گرفته شده است. در داخل متد اطلاعاتی از شی مشخص می شود و هر دو مقدار رشته ای بدست می آید . هم چنین مقدار Reference با کلمه کلیدی ref بدست می اید. در مثال زیر مشاهده نمایید :

    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Text;  
      
    namespace OPPS  
    {  
        public class PersonInfo  
        {  
      
            static void PersonAge1(ref int age) // 1st Person  
            {  
                age = 25;  
            }  
            static void PersonAge2(ref int age) // 2nd Person  
            {  
                age = 28;  
            }  
            static void Main(string[] args)  
            {  
                int age = 0;  
      
                PersonAge1(ref age);  
                Console.WriteLine("1st Person Age : {0} ",age);  
      
                PersonAge2(ref age);  
                Console.WriteLine("2st Person Age : {0} ",age);  
      
               Console.ReadLine();  
                 
            }  
              
        }  
    }  

خروجی :

ارسال از طریق reference خارجی(Pass by out reference) :

 در اینجا هم مقدار reference توسط کلید واژه out بدست می آید که در این مثال فرق بین ref و out را می بینید.هر دوی آن ها در زمان کامپایل برنامه توسط کلید واژه ref و out چک می شوند . لازم است که reference خارجی   هر نوع خروجی کامل را در برنامه بدهد. 

    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Text;  
      
    namespace OPPS  
    {  
        public class PersonInfo  
        {  
      
            static void PersonAge1(ref int age) // 1st Person with ref   
            {  
                 
            }  
            static void PersonAge2(out int age) // 2nd Person with out  
            {  
                age = 28;  
            }  
            static void Main(string[] args)  
            {  
                int age = 0;  
      
                PersonAge1(ref age);  
                Console.WriteLine("1st Person Age : {0} ",age);  
      
                PersonAge2(out age);  
                Console.WriteLine("2nd Person Age : {0} ",age);  
      
               Console.ReadLine();  
                 
            }  
              
        }  
    }  

خروجی :

این روش نوع مقدار ref را اعلان نمی کند پس مقدار 0 به خروجی داده می شود.

اگر نوع مقدار out اعلان نشده است در زمان کامپایل خطا داده می شود.

کپسوله سازی (Encapsulation) :

کپسوله سازی یک نوع سطح دسترسی است که برای دسترسی و قابلیت رویت بودن برای اعضای یک کلاس است .کپسوله سازی در #C لیستی که در ادامه به آنها اشاره شده است  را پشتیبانی نمیکند. 

1. Public

2. Private

3. Protected

4. Internal

5. Protected Internal 

بنابراین کپسوله سازی با توجه به کلمات کلیدی بالا سطح دسترسی را برای داده یا اطلاعات را تعریف می کند. در حال حاضر ما برخی اطلاعات در مورد دسترسی به کلمه کلیدی را یک به یک می گیریم .

عمومی(public) :

کلیدواژه سطح دسترسی عمومی یک کلاس متغیر یا تابع است و می تواند توسط هر شی دیگر یا تابع دسترسی داشته باشد. خارج از کلاس هم می توانیم به آن دسترسی داشته باشیم. 

مثال:

    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Text;  
      
    namespace OPPS  
    {  
        public class PublicDemo  
        {  
            class Maths  
            {  
                // declare variable   
                public int a;  
                public int b;  
      
                public int GetValue()  
                {  
                    return a + b;  
                }  
                public void ShowResult()  
                {  
                    Console.WriteLine("Value of A: {0}",a);  
                    Console.WriteLine("Value of B: {0}", b);  
                    Console.WriteLine("Result = {0}",GetValue());  
                    Console.ReadLine();  
                }  
            }  
            static void Main(string[] args)  
            {  
                Maths m = new Maths();  
                m.a = 5;  
                m.b = 2;  
                m.ShowResult();  
                Console.ReadLine();  
            }  
         }  
    }  

 

خروجی :

در اینجا می بینید که متغیرهای a,b به عنوان public و برای دسترسی با کلاس Maths به عنوان m  در نظر گرفته می شود. همچنین ایجاد  تابع GetValue() و ShowResult() برای دسترسی متغیرها می باشد .

خصوصی (private) :

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

مثال:

    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Text;  
      
    namespace OPPS  
    {  
        public class PublicDemo  
        {  
            class Maths  
            {  
                // declare variable   
                private int a;  
                private int b;  
      
                public void InsertValue()  
                {  
                    Console.WriteLine("Enter value of A:");  
                    a = Convert.ToInt32(Console.ReadLine());  
                    Console.WriteLine("Enter value of B:");  
                    b = Convert.ToInt32(Console.ReadLine());  
                }  
                public int GetValue()  
                {  
                    return a + b;  
                }  
                public void ShowResult()  
                {  
                    Console.WriteLine("=============================");  
                    Console.WriteLine("Value of A: {0}",a);  
                    Console.WriteLine("Value of B: {0}", b);  
                    Console.WriteLine("Result = {0}",GetValue());  
                }  
            }  
            static void Main(string[] args)  
            {  
                Maths m = new Maths();  
                m.InsertValue();  
                m.ShowResult();  
                Console.ReadLine();  
            }  
         }  
    }  

خروجی:

در این مثال a,b به عنوان private شناسایی شده است و بنابراین در اینجا ایجاد تابع InsertValue() و GetValue() دسترسی به مقادیر هستند.

Protected :

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

مثال:

    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Text;  
      
    namespace OPPS  
    {  
        public class MathsDemo  
        {  
            class Maths1  
            {  
                public int R;  
                protected int J;  
            }  
            class Maths2 : Maths1  
            {  
                public int AddValue()  
                {  
                    R = 5;  
                    J = 29;  
                    return R + J;  
                }  
            }  
            static void Main(string[] args)  
            {  
                Maths2 m2 = new Maths2();  
                m2.R = 5;  
                m2.J = 29;  //--------------------- خطا -------------  
                Console.WriteLine(m2.AddValue());  
                Console.ReadLine();  
            }  
         }  
    }  

در مثال قبلی می بینید که شی از کلاس Maths1 فراخوانی نمی کند اما کلاس Maths1 از Maths2 ارث برده است. در اینجا با توجه به خط خطا به دلیل J می باشد که به عنوان Protected شناسایی نشده است . بنابراین عضو protected نمیتواند خارج از فرزند دسترسی داشته باشد بلکه تنها فقط به داخل فرزند دسترسی دارد. 

داخلی (Internal) :

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

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

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

مثال :

    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Text;  
      
    namespace OPPS  
    {  
        public class InternalDemo  
        {  
            class Result  
            {  
                internal int a;  
                internal int b;  
      
                int Addition()  
                {  
                    return a + b;  
                }  
                public void ShowResult()  
                {  
                    Console.WriteLine("Value of A:{0}",a);  
                    Console.WriteLine("Value of B:{0}", b);  
                    Console.WriteLine("Addition: A + B = {0}",Addition());  
                }  
            }  
            static void Main(string[] args)  
            {  
      
                Result R = new Result();  
                R.a = 3;  
                R.b = 4;  
                R.ShowResult();  
                Console.ReadLine();  
            }  
         }  
    }  

خروجی :

در این مثال می بینید که Addition() هیچ سطح دسترسی شناخته نشده است . 

Proctected internal :

سطح دسترسی کلمه کلیدی Proctected internal اجازه می دهد که اعضا و مقادیر داخل آن به کلاس و کلاس مشتق آن یا به فضای نام داخل موجود قابل دسترسی باشد. متد نمی تواند از یک کلاس در اسمبلی یا فایل دیگر دسترسی داشته باشد . 

به عبارت دیگر تعیین سطح دسترسی داخلی proctected اجازه می دهد تا اعضای خود را در داخل همان کلاس و کلاس هایی که از این کلاس مشتق شده اند دسترسی داشته باشد . 

    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Text;  
      
    namespace OPPS  
    {  
        public class Protected_Internal  
        {  
            class DisplayWord  
            {  
                protected internal string word;  
      
                public void ShowName()  
                {  
                    Console.WriteLine("\n You are Enter Word :" + word);  
                }  
            }  
              
            static void Main(string[] args)  
            {  
                DisplayWord ND = new DisplayWord();  
                Console.WriteLine("Enter Some Word :");  
                ND.word = Console.ReadLine();  
                ND.ShowName();  
                Console.ReadLine();  
                 
            }  
         }  
    }  

 

خروجی :

چندریختی (Polymorphism( :

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

Static Polymorphism(چندریختی استاتیک) دو تکنیک برای زمان اجر ای استاتیک ارائه می دهد:

                 - سربارگذاری از حد عملکرد (function overloading)

                 - سربارگذاری اپراتور (operator overloading)

سربارگذاری از حد عملکرد (function overloading):

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

یک مثال در زیر مشاهده نمایید :

    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Text;  
      
    namespace OPPS  
    {  
        public class Polymorphism  
        {  
            void DataDisplay(int n)  
            {  
                Console.WriteLine("Display numaric value:{0} ", n);  
                  
            }  
            void DataDisplay(string str)  
            {  
                Console.WriteLine("Display String Value:{0} ", str);  
                 
            }  
            static void Main(string[] args)  
            {  
                Polymorphism P = new Polymorphism();  
                P.DataDisplay(404);  
                P.DataDisplay("CSharp");  
                Console.ReadKey();  
           
            }  
         }  
    }  

خروجی:

 

همان طور که در این مثال می بینید DataDisplay() شامل خروجی مختلف با آرگومان های مختلف میباشد . اما DataDisplay تابع یکسانی می باشد.

مثالی از سربارگذاری اپراتور (operator overloading) :

    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Text;  
      
    namespace OPPS  
    {  
        class RectAngal  
        {  
            private int height;  
            private int width;  
             
            public void Rectheight(int h)  
            {  
                height = h;  
            }  
            public void Rectwidth(int w)  
            {  
                width = w;  
            }  
            public int RectArea()  
            {  
                return height * width;  
            }  
            public static RectAngal operator +(RectAngal rH, RectAngal rW)  
            {  
                RectAngal Rect = new RectAngal();  
                Rect.height = rH.height + rH.height;  
                Rect.width = rH.width + rW.width;  
                return Rect;  
            }  
        }  
        public class OperatorOverload  
        {  
            static void Main(string[] args)  
            {  
                int Area1, Area2;  
                RectAngal R_Angal_1_Area = new RectAngal();  
                RectAngal R_Angal_2_Area = new RectAngal();  
      
                R_Angal_1_Area.Rectheight(5);  
                R_Angal_1_Area.Rectwidth(4);  
      
                R_Angal_2_Area.Rectheight(3);  
                R_Angal_2_Area.Rectwidth(4);  
      
                Area1 = R_Angal_1_Area.RectArea();  
                Area2 = R_Angal_2_Area.RectArea();  
      
                Console.WriteLine("Rectangal 1 Area :{0} ", Area1);  
                Console.WriteLine("Rectangal 2 Area :{0} ", Area2);  
                Console.ReadLine();  
            }  
         }  
    }  

خروجی:

Dynamic Polymorphism(چندریختی پویا) :

زمان اجرای چندریختی ، داینامیک (پویا) است . هم چنین به عنوان یک متد مهم شناخته شده است . متد overriding یعنی با داشتن دو یا چند متد با یک نام و یک مشخصه یکسان ولی با پیاده سازی متفاوت می باشد. پس در متد override ، متد overriding را فراخوانی می کند.

در متد override قانون وراثت را توسط کلمه کلیدی override و virtual استفاده می کند. 

مثال:

    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Text;  
      
    namespace OPPS  
    {  
        class Person  
        {  
            public virtual void display()  
            {  
                Console.WriteLine(" Person ");  
            }  
        }  
        class Student : Person  
        {   
            public override void display()  
            {  
                Console.WriteLine(" Student ");  
            }  
        }  
        class Program  
        {  
            static void Main(string[] args)  
            {  
                Person P ;  
                P= new Person();  
                P.display();  
      
                P = new Student();  
                P.display();  
                  
                Console.ReadLine();  
            }  
        }   
    }  

 

خروجی :

کلاس Abstract و متد Abstract

کلاس Abstract :

کلید واژه abstract برای کلاس و متد استفاده شده است . یک کلاس abstract نمی تواند یک نمونه به عنوان شی باشد و تنها به منظور زیر کلاس ها می باشد و یکسری محدودیت هایی هم دارد و نمی تواند سازنده (constructed)  باشد و متد Abstract هیچ بدنه ای ندارد .

اعلان کلاس Abstract :


    public abstract class className  
    {  
      
    }  

هنگامی که یک کلاس به عنوان کلاس Abstract اعلان کرد بعد از آن ممکن نیست که یک نمونه برای آن کلاس

ایجاد شود اما می تواند به عنوان یک پارامتر در متد استفاده شود. 

مثال:


    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Text;  
      
    namespace OPPS  
    {  
        public abstract class BaseClass  
        {  
            public abstract string GetAbstractData();  
      
            public virtual string GetVirtualData()  
            {  
                return "Base Virtual Data";  
            }  
            public string GetData()  
            {  
                return "Base Get Data";  
            }  
        }  
        public class DerivedClass : BaseClass  
        {  
            public override string GetAbstractData()  
            {  
                return "Derived Abstract Data";  
            }  
      
            public override string GetVirtualData()  
            {  
                return "Derived Virtual Data";  
            }  
      
            public string GetData()  
            {  
                return "Derived Get Data";  
            }  
        }  
        class Program  
        {  
      
            static void Main(string[] args)  
            {  
                BaseClass ABS = new DerivedClass();  
      
                Console.WriteLine(ABS.GetAbstractData());  
                Console.WriteLine(ABS.GetVirtualData());  
                Console.WriteLine(ABS.GetData());  
      
      
                DerivedClass DRD = new DerivedClass();  
      
                Console.WriteLine(DRD.GetAbstractData());  
                Console.WriteLine(DRD.GetVirtualData());  
                Console.WriteLine(DRD.GetData());  
      
      
                Console.ReadLine();  
            }  
        }  
    }  

خروجی :

چندریختی داینامیک با کلاس Abstract و متد مجازی ( Dynamic Polymorphism with AbstractClass and virtual method)  :

برخی از کلمات کلیدی برای وراثت در زبان برنامه نویسی شی گرایی استفاده می شود و  Abstrac  و مجازی  (virtual)  در سی شارپ استفاده می شود و همچنین از روش های override هم استفاده می شود.

در این جا یک مثال برای کلاس Abstract و متد مجازی را مشاهده کنید :

مثال:

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
  
namespace OPPS  
{  
    public abstract class BaseClass  
    {  
        public abstract string GetAbstractData();  
  
        public virtual string GetVirtualData()  
        {  
            return "Base Virtual Data";  
        }  
        public string GetData()  
        {  
            return "Base Get Data";  
        }  
    }  
    public class DerivedClass : BaseClass  
    {  
        public override string GetAbstractData()  
        {  
            return "Derived Abstract Data";  
        }  
  
        public override string GetVirtualData()  
        {  
            return "Derived Virtual Data";  
        }  
  
        public string GetData()  
        {  
            return "Derived Get Data";  
        }  
    }  
    class Program  
    {  
  
        static void Main(string[] args)  
        {  
            BaseClass ABS = new DerivedClass();  
  
            Console.WriteLine(ABS.GetAbstractData());  
            Console.WriteLine(ABS.GetVirtualData());  
            Console.WriteLine(ABS.GetData());  
  
  
            DerivedClass DRD = new DerivedClass();  
  
            Console.WriteLine(DRD.GetAbstractData());  
            Console.WriteLine(DRD.GetVirtualData());  
            Console.WriteLine(DRD.GetData());  
  
  
            Console.ReadLine();  
        }   

خروجی:

 اگر دقت کنید بیشتر از یک خروجی را میبینیم. 

GetVirtualData()  
GetData()

حالا در کلاس  Derived متد و خروجی را میبینید ، که چه اتفاقی می افتد.

خروجی:

کلاس Sealed :

کلاس sealed به عبارت ساده تر از هیچ کلاسی ارث بری نمی کند و با کلمه کلیدی و نام کلاس ایجاد می شود. کلاس Sealed نمی تواند کلاس مشتق باشد . 

مثال :


    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Text;  
      
    namespace OPPS  
    {  
        
        class Program  
        {  
            public abstract class Triangle  
            {  
                private double W;  
                private double H;  
      
                public Triangle(double length = 0D, double height = 0D)  
                {  
                    W = length;  
                    H = height;  
                }  
      
                public virtual double Area()  
                {  
                    return W * H / 2;  
                }  
      
                public void Display(string D = "")  
                {  
                    Console.WriteLine("Triangle  {0}", D);  
                    Console.WriteLine("--------------------------");  
                    Console.WriteLine("Triangle Width:    {0}", W);  
                    Console.WriteLine("Triangle Height:   {0}", H);  
                    Console.WriteLine("Triangle Area:     {0}", Area());  
                }  
            }  
      
            sealed public class SealedDemo : Triangle  
            {  
                public SealedDemo(double Width, double Height): base(Width, Height)  
                {  
                }  
            }  
            static void Main(string[] args)  
            {  
                SealedDemo SD = new SealedDemo(5.3, 8.5);  
                SD.Display("         OUTPUT");  
                Console.ReadLine();  
            }  
        }  
    }  

خروجی :

ارث بری (Inheritance) :

ارث بری یکی از مهم ترین مفاهیم اولیه شی گرایی (opp) می باشد . ارث بری قابلیت استفاده مجدد کد موجود را در یک زبان برنامه نویسی فراهم میکند.

C# فقط از یک کلاس ارث بری پشتیبانی میکند. 

مثال :


    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Text;  
      
    namespace OPPS  
    {  
        class RectangleValue    //Base Class  
        {  
            protected int height, width;  
      
            public void Rect_Hight(int h)  
            {  
                height = h;  
            }  
            public void Rect_Width(int w)  
            {  
               width = w;  
            }  
        }  
      
        class Rectangle : RectangleValue    // RectangleValue Resue   
        {  
            public int RectangleArea()  
            {  
                return (height * width);  
            }  
        }  
        class Inheritance  
        {  
            static void Main(string[] args)  
            {  
                Rectangle R = new Rectangle();  
                R.Rect_Hight(5);  
                R.Rect_Width(8);  
                Console.WriteLine("RectAngle Area:{0}", R.RectangleArea());  
                Console.ReadLine();  
            }  
        }  
    }  

خروجی :

در مثال قبلی می بینید که کلاس RectangleValue  یک بار اجرا میشود و از کلاس دیگر برای پیدا کردن مساحت مستطیل استفاده می شود. در #c  ارث بری چندگانه را پشتیبانی نمی کند. بنابراین در #c برای اماده کردن ارث بری چندگانه می تواند از رابط استفاده کند. 

رابط (Interface) :

رابط مانند یک نوع کلاس است ولی پیاده سازی نمی شود اما فقط با هر متد یا خواص شناخته می شود.

با استفاده از مثال قبلی در اینجا مثال رابط ارث بری را مشاهده نمایید :

مثال :


    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Text;  
      
    namespace OPPS  
    {  
        class RectangleValue    //Base Class  
        {  
            protected int height, width;  
      
            public void Rect_Hight(int h)  
            {  
                height = h;  
            }  
            public void Rect_Width(int w)  
            {  
               width = w;  
            }  
        }  
      
        public interface TriAngle  
        {  
            int TriAngleArea(int area);  
      
        }  
      
      
      
        class Rectangle : RectangleValue, TriAngle   // using interface class   
        {  
            public int RectangleArea()  
            {  
                return (height * width);  
            }  
            public int TriAngleArea(int area)  
            {  
                return area/2;  
            }  
        }  
      
      
        class Inheritance  
        {  
            static void Main(string[] args)  
            {  
                int area;  
                Rectangle R = new Rectangle();  
                R.Rect_Hight(5);  
                R.Rect_Width(8);  
                area = R.RectangleArea();  
                Console.WriteLine("RectAngle Area:{0}", R.RectangleArea());  
                Console.WriteLine("TriAngle Area:{0}", R.TriAngleArea(area));  
                Console.ReadLine();  
            }  
        }  
    }  

خروجی :

سازنده و مخرب   (Constructor و Destructor) :

سازنده (Constructor) :

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

I. سازنده پیش فرض (Default Constructor) :

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

مثال :


    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Text;  
      
    namespace OPPS  
    {      
        class Constructor  
        {          
            class DefaultConstructor  
            {   
                int a, b;  
                public DefaultConstructor()  
                {  
                    a=5;   
                    b=10;  
                }  
                public void OutPut()  
                {  
                Console.WriteLine("Value of A = {0}",a);  
                Console.WriteLine("Value of B = {0}", b);  
                }  
            }  
            static void Main(string[] args)  
            {  
                DefaultConstructor DC = new DefaultConstructor();  
                DC.OutPut();  
                Console.ReadLine();  
            }  
        }  
    }  

خروجی :

II.سازنده پارامتر (Parameterized) :

در سازنده پارامتر حداقل یک پارامتر می تواند به سازنده منتقل کند. 

مثال :


    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Text;  
      
    namespace OPPS  
    {      
        class Constructor  
        {  
            class PerameterConstructor  
            {   
                int a, b;  
                public PerameterConstructor(int i, int j)       // Pass parameter  
                {  
                    a=i;   
                    b=j;  
                }  
                public void OutPut()  
                {  
                Console.WriteLine("Value of A = {0}",a);  
                Console.WriteLine("Value of B = {0}", b);  
                }  
            }  
            static void Main(string[] args)  
            {  
                PerameterConstructor DC = new PerameterConstructor(5,3);      // Pass parameter value  
                DC.OutPut();  
                Console.ReadLine();  
            }  
        }  
    }  

خروجی :

III. کپی سازنده (Copy Constructor) :

کپی سازنده یک سازنده است که یک شی جدید از طریق ساخت یک کپی از یک شی موجود را ایجاد می کند. 

مثال :


    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Text;  
      
    namespace OPPS  
    {      
        class Constructor  
        {  
            class CopyConstructor  
            {   
                int a, b;  
                public CopyConstructor(int i, int j)     
                {  
                    a=i;   
                    b=j;  
                }  
                public CopyConstructor( CopyConstructor c)  
                {  
                    a = c.a;  
                    b = c.b;  
                }  
                public void OutPut()  
                {  
                Console.WriteLine("Value of A = {0}",a);  
                Console.WriteLine("Value of B = {0}", b);  
                }  
            }  
            static void Main(string[] args)  
            {  
                CopyConstructor CC = new CopyConstructor(5,3);       
                CopyConstructor copy = new CopyConstructor(CC);  
                CC.OutPut();  
                Console.WriteLine("------- VALUE COPY ----------");  
                copy.OutPut();  
                Console.ReadLine();  
            }  
        }  
    }  

خروجی :

 

IV.سازنده استاتیک (Static Constructor) :

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

مثال :

namespace OPPS  

{      

    class Static  

    {  

        class Base  

        {  

            static Base()   

            {  

                Console.WriteLine("Base");   

            }  

            public Base()   

            {   

                Console.WriteLine("Base");   

            }  

              

        }  

        class Derived : Base  

        {  

            static Derived()   

            {   

                Console.WriteLine("Derived");   

            }  

            public Derived()   

            {   

                Console.WriteLine("Derived");   

            }  

             

        }  

        static void Main(string[] args)  

        {  

            Console.WriteLine("Static Demo");  

            new Derived();  

            Console.ReadLine();  

        }  

    }  

}  

 

خروجی :

 

سازنده خصوصی (Private Constructor) :

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

ایجاد اشیای کلاس به صورت مستقیم ممکن نیست .

مثال :


    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Text;  
      
    namespace OPPS  
    {      
        class Private  
        {  
            public class PageHit  
            {  
                private PageHit()   
                {  
                }  
                public static int currentCount;  
                public static int IncrementCount()  
                {  
                    return currentCount++;  
                }  
            }  
              
            static void Main(string[] args)  
            {  
                PageHit.currentCount = 20;  
                PageHit.IncrementCount();  
                Console.WriteLine("Number of time Page Hit: {0}", PageHit.currentCount);  
                Console.ReadLine();  
            }  
        }  
    }  

خروجی :

 

همان طور که در مثال بالا میبینید PageHit.currentCount=20 و وقتی که برنامه را اجرا میکنید 1   واحد به مقدار اولیه اضافه میشود و خروجی 21 میدهد. 

مخرب (Destructor) :

مخرب برای از بین بردن یک کلاس استفاده می شود . هر کلاس تنها یک مخرب دارد. مخرب یک متدی است که در کلاس هم نام به عنوان کلاس قبلی با نماد ~ شروع می شود .

دستور :

~ ClassName()
{
}

مثال :


    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Text;  
    namespace OPPS  
    {  
       public class DemoClass  
       {  
          public DemoClass()  
          {  
             Console.WriteLine("Create Class");  
          }  
          ~DemoClass()  
          {  
             Console.WriteLine("Class Destroyed");  
          }  
       }  
       class Destructor  
       {  
          public static void DC_Create()  
          {  
             DemoClass DC = new DemoClass();  
          }  
          static void Main(string[] args)  
          {  
             DC_Create();  
             GC.Collect();  
             Console.ReadLine();  
          }  
       }  
    }  

 

خروجی :