در قسمت دوم آموزش شی گرایی در ادامه آموزش دوم درباره سطوح کنترل Protected و Internal صحبت خواهیم کرد همچنین مباحث پارامتر در متد ها و دونوع اصلی پروپرتی ها را نیز آموزش میدهیم.
در ادامه آموزش قبل ما متدی ساده برای جمع مبلغ محصول و یک مقدار اضافی را به صورت زیر در فایل کلاس خود ایجاد کرده
public double Add(double price , double rate) { return price + rate; }
حال میخواهیم در پنجره خروجی ابتدا نام شی را و سپس مبلغ نهایی که با استفاده از متد به دست می آید را نمایش دهد پس در قسمت main برنامه چنین کدنویسی می کنیم
static void Main(string[] args) { Product obj = new Product(); obj._name = "T_shirt"; obj._price = 15000; Console.WriteLine(obj._name +" " + obj.Add(obj._price,5000)); Console.ReadKey(); }
در عبارات فوق ابتدا شی از نوع کلاس ایجاد کرده و سپس مقادیری را با استفاده از پروپرتی هایی که از قبل برای فیلدهای کلاس ایجاد کرده ایم به فیلد های کلاس ارسال میکنیم و در انتها نیز هنگام چاپ مقادیر ابتدا مقدار پروپرتی _name (که با اینکار قسمت get پروپرتی فراخوانی میشود) و سپس متدAdd را فراخوانی کرده و دو مقدار مربوطه را به متد ارسال میکنیم که در انتها مقدار نهایی که متد بازمیگرداند چاپ میشود.
در مثال فوق برای ما مشخص بود که میخواهیم تنها و تنها دو مقدار را به متد ارسال کرده و روی آنها کار کنیم اما گاهی ممکن است برای ما مشخص نباشد که بروی چه تعداد از مقادیر میخواهیم کار کنیم پس در این زمان است که باید از عبارت params به صورت زیر در فایل کلاس استفاده کنیم
public double Add(params double[] data) { double result = 0; foreach(var i in data ) { result += i; } return result; }
همانگونه که مشاهد میکنیم در قسمت پارامترهای متد ابتدا کلمه کلیدی params سپس نوع داده هایی که به متد ارسال میشوند سپس علامت [] و در انتها نیز نامی برای پارامترها قرار میدهیم در بدنه متد نیز پس از ایجاد کردن متغیری برای قرار گیری نتیجه از حلقه foreach استفاده کرده تا به تمامی عناصر موجود در data دسترسی پیدا کرده و همه را با هم جمع کند و نتیجه نهایی را که در result قرار دارد return میکند.
با این روش میتوان به هر تعداد مقادیر به این متد ارسال کرده نتیجه موردنظر را گرفت برای مثال در همان مثال قبل میتوان بجای قرستادن دو مقدار price و ۵۰۰۰ به صورت زیر نیز نوشت
Console.WriteLine(obj._name +" " + obj.Add(obj._price,5000,2000,0.50));
و نتیجه نیز بدین صورت خواهد بود
این گونه پروپرتی ها همانگونه که از نامش مشخص است یا فقط خواندی و یا فقط نوشتنی هستند بدین معنی که یا قسمت get{} را ندراند یا قسمت set{} توجه داشته باشید که میتوانند تنها یکی از اینها را از دست بدهند چون در صورت از دست دادن هردو با خطا مواجه خواهید شد.
حال اگر ما قسمت get{} پروپرتی را حذف کنیم آنگاه دیگر نمیتوان به مقدار درونی آن دسترسی پیدا کرد مثلا خط کد زیر با خطا مواجه میشود
Console.WriteLine(obj._price);
چون خط فوق قسمت get را فراخوانی میکند و این قسمت نیز از پروپرتی حذف شده پس با خطا مواجه میشود اما دستوراتی که مربوط به مقداردهی و set{} میباشد هیچ مشکلی ندارند مانند خط زیر
obj._price = 155;
پس در این صورت پروپرتی ما به فقط نوشتنی تبدیل خواهد شد.
پروپرتی فقط خواندنی نیز پروپرتی است که تنها قسمت get{} آن موجود و فعال باشد و قسمت set{} آن حذف شده باشد که در این صورت نیز هیچگونه مقداردهی نمیشود انجام داد و تنها میتوان مقدار را فراخوانی کرده و دستوراتی مانند دستور زیر بکار برد
Console.WriteLine(obj._price);
در آموزش قبل دو سطح Private و Public را مفصل توضیح دادیم حال به توضیح این دو سطح میپردازیم.
سطح دسترسی Protected در واقع تلفیقی از Public و Private میباشد بدین صورت که عضوهای Protected علاوه بر اینکه از درون کلاس قابل دسترسی است در کلاس های دیگر که از کلاس جاری ارث بری(مبحث ارث بری را در ادامه آموزش بطور مفصل شرح خواهیم داد) میکنند نیز قابل دسترسی است ولی از بیرون از کلاس قاب دسترسی نمیباشد پس در حالتی که در بیرون از کلاس غیر قاب دسترسی میباشد مانند Private و در حالت ارث بری از کلاس جاری که قابل دسترسی است همانند Public میباشد
سطح Internal نیز عضوهایش را تنها در اسمبلی جاری قابل دسترسی میکند حال توضیح مختصری که دررابطه با اسمبلی میتوانیم بدهیم این است که هنگام Build کردن پروژه یک اسمبلی ایجاد میکند که شامل فایلهای .dll , .exe میباشد که مجموعه از یک سری عملیات کاری میباشند و درواقع منابع قابل استفاده در پروژه ما میباشد و درواقع هنگام استفاده از internal میگوییم تنها در اسمبلی جاری قابل دسترسی باشد و class ها خود نیز به طور پیشفرض از نوع internal میباشند.