مشاهده نسخه کامل
: Abstract و Interface در سی شارپ
سلام
دوستان من الان حدودا 20-30 تا مطلب در مورد این 2 تا مورد خوندم. میتونم باهاشون کد بزنم و پیاده سازی بکنم و مشکلی ندارم.
اما واقعیت من اصلا درک نمیکنم که چه وقت و کجا باید هر کدام را استفاده کرد؟
بعضا یک سری مثال ها خوندم که اصلا ادم رو گیج تر میکنند و مثال هاشون هم شبیه هم هستت. :n03:
این قدر فهمیدیم که وقتی بخواهیم بگوئیم،چه کاری انجام شود و بدون اینکه چطور انجام شود اینترفیس میزنیم. اما اگر نیاز به جزئیات و کد بیشتر باشد.abstract میزنیم.
اگر فقط همین هست که دیگر نیاز به دو مفهوم نبود.یکی شو پیاده میکردن و دست برنامه نویس میزاشتن. اگر این طور هست پس abstarct هم کار اینترفیس را انجام میدهد و لزوم به وجود اینترفیس نیست!!!!!!!!!!!!!!!
سلام
تفاوت abstarct و interface بسیار اساسی تر و بزرگتر از شباهت اندک و بسیار ناچیز آنها است.
abstarct ها کلاس هستند میتوانند، بسیار شبیه سایر class ها...
میتوانند هزاران خط کد داشته باشند، فقط از یک کلاس دیگر ارث بری داشته باشد و کلاس دیگری از آنها ارث ببرد.
متدهای کلاس پایه خود را باز تعریف کنند.
متغییر داشته باشند.
در دات نت همواره با مرجع منتقل میشوند و در حافظه هیپ بارگذاری میشوند.
میتوانند چندین interface را درون خود پیاده سازی کنند.
اعضای آنها میتواند دارای کد و با حوزه دید (public,private,internal...) دلخواه باشند.
در مقابل interface ها گونه ای مجزا هستند (نه class و نه struct) در این حال میتوانند هم در class و هم در struct پیاده سازی شوند.
فاقد هرگرونه پیاده سازی و کد و حتی متغییر هستد.
فقط شامل تعریفی از اعضای اجباری هستند که همگی ضمنی public هستند.
نمیتوانند از class ارث بری داشته باشند.
در سایر class و struct ها میتوانید بارها و در سلسه مراتب مختلف وراثتی تنوع بسیار زیادی از آنها را پیاده سازی کنید.
از زاویه دیگر وقتی ما در حال نوشتن یک کلاس هستیم، فقط میتوانیم از یک کلاس خاص وراثت بگیریم (abstarct یا غیر abstarct) ولی در پیادی سازی interface ها محدودیتی نداریم.
به عنوان نمونه اگر کلاس ما نوعی List باشد (وراثت List) باشد، و بخواهیم امکانات آن را به ارث ببریم، دیگر نمیتوانیم همزمان یک abstarct دیگر را هم در آن داشته باشیم.
در واقع وراثت های ما یگانه است، یک "پراید" باید وراثت "خودرو سواری" باشد و یک "خرگوش" وراثت "حیوانات" ...
شباهت و ارث بری "پراید از خودرو" و "خرگوش از حیوانات" بسیار منطقی و نزدیک است ولی این دو موجودیت به ظاهر بسیار متفاوت از دو شاخه کاملاً متفاوت وراثتی باز هم یک سری تجهزات و امکانات مشترک، مانند تغذیه و حرکت و... دارند...
این رفتار های مشترک در برنامه نویسی به کمک interface ها پوشش داده میشود.
نمونه عملی تر از خود فریم ورک:
واسط IEnumerable را در نظر بگیرید، اعلان میکند که شی دارای آن یک فهرست شمارش پذیر از فرزندانی را شامل میشود.
این تعریف خیلی کلی و گسترده است، این هیچگاه نمیتواند یک abstarct باشد.
یک Array فهرستی از عناصر است
یک List و حتی یک Dictionary هم فهرستی از عناصر دارند.
یک String هم فهرستی از Char ها دارد...
این چهارکلاس از شاخه های کاملاً مجزای وراثتی هستند و معنی ندارد که وراثت مشترکی باشند (مگر چیز بسیار کلی مانند object)
منظور ان است که این کلاسها توابع و متد و خصایص کاملاً متفاوتی دارند و بجز IEnumerable ویژگی های دیگری هم دارند.
در واقع برای یک کلاس فقط میتوانیم یکبار وراثت بگیریم که کد کامل کلاس پایه هم منتقل میشود و باید ان را برای مهم ترین اشتراک با پایه خرجش کنیم، یک کلاس نمیتواند از دو کلاس پایه (abstarct) وراثت بگیرید.
در ادامه مثال واسط دیگری مانند ICloneable داریم که اشاره میکند کلاس مورد نظر توانایی کپی شدن کامل (Duplicate) را دارد.
دقت کنید این چیزی نیست که بگوییم ویژه فلان کلاس ها است، هر کلاسی در هر شاخه و هر نوعی میتواند همچین خاصیتی داشته باشد...
میخواهد یک Image باشد یا یک Hashtable یا یک String ... !
نکته جالب آن است که اگر IEnumerable و ICloneable کلاس بودند (abstarct یا غیر abstarct فرقی ندارد) دیگر نمیشد String هم IEnumerable باشد و هم ICloneable و هم IComparable و IConvertible و IEquatable و...
یا Hashtable همزمان کلیه واسطهای IEnumerable و ICloneable و ISerializable و... را دارد که اگر بجای این interface ها class بودند (abstarct یا غیر abstarct) مجدد Hashtable باید یکی از آنها را میداشت.
مثال غیر برنامه نویسی:
الف)
یک گوشی موبایل باید حداقل امکانات انتظاری از یک موبایل را داشته باشد ولی میتواند یکسری ویژگی ها متعدد دیگر هم داشته یا نداشته باشد...
دوربین عکاسی، GPS، اتصال به اینترنت، پخش موسیقی، فیش 3.5mm و...
یک گوشی HTC باید وراثتی از موبایل باشد (class) ولی سایر امکانات آن که میتواند باشد یا نباشد باید ویژگی (interface) آن باشند.
(دقت که که وسایلی که شاید اصلاً موبایل هم نباشند، امکان دارد این ویژگی ها اضافه را داشته باشند، یک تلویزیون هم فیش 3.5mm صوتی را دارد!)
ب)
در مورد یک خودرو هم شاید شاید بتوانید کلاس پایه ان (abstarct یا غیر abstarct) ان را به موتور ماشین تشبیه کنیم که فقط یکی میتواند باشد و اصل ماشین را هم شامل میشودف در عین حال موتور تکی قابلیت حرکت ندارد و نیاز به بخش های جانبی (سیستم سوخت و فرمان و ترمز و بدنه و...) دارد تا توانایی کاربردی نهایی را پیدا کند.
اگر موتور ماشین را کلاس پایه ان فرض کنیم سایر امکانات رنگارنگ خودرو میتواند interface ها باشد.
ج)
قبلاً هم گفتم، نزدیک ترین معادل Interface ها در دنیای واقعی میتوان فیش ها و سوکت های وسایل الکتریکی تشبیه کرد.
یک تلویزیون، دوشاخ برق دارد! فیش آنتن دارد، فیش هایی برای ویدئو و خروجی صوتی دارد. (چندین فیش)
یک ماشین ریش تراش هم دوشاخ دارد! که بسیار هم شبیه دوشاخ تلویزیون است.
یک MP3 جیبی هم فیش صوتی دارد، که باز هم بسیار شبیه فیش تلویزیون است!
اینها همان Interface ها در دنیای برنامه نویسی هستند.
از زاویه دیدی یک دوشاخ شاید خیلی چیز مهمی نباشد! هیچ قطعه ای هم ندارد، کاملاً پوچ و در ظاهر غیر مهم.
ولی از زاویه دیگر همین دوشاخ اگر با پریز خانه شما مچ نباشد، نمیتواند تلویزیون گران قیمت خود را روشن کنید.
این همان Interface است، فاقد هرگونه کد و بظاهر پوچ و تهی! ولی از زاویه درست بسیار مهم و ارزشمند.
Interface ها اجازه میدهد کلاس های شما از شاخه های وراثتی مختلف (تلویزیون در برابر ریش تراش) از شرکت های متعدد با سال ساخت متفاوت (تلویزیون در برابر برق کشی منزل تان) با هم و در کنار هم کار کنند.
Interface نوعی استاندارد سازی را ایجاد میکند، طوری که دو طرف درگیر کمترین اطلاعی از عملکرد هم نداشته باشند.
شاید موقعی که خانه ما برق کشی میشد، رایانه وجود نداشته، ولی الآن راینه خود را به راحتی به برق خانه متصل میکنیم!
چون این دوشاخ و پریز به ظاهر بی ارزش، استانداری ارتباطی بین این دو تعریف میکند که هر طرف ان را پشتیبانی کند به راحتی با دیگری کار خواهد کرد.
نکته:
درواقع تعریف یک کلاس که بیشتر متدهای ان abstarct باشند بی معنی و بی ارزش است.
شما باید موقعی از class و abstarct استفاده کنید که کلاس پایه شما بخش زیادی از کارها را با کد خود انجام دهد و کلاس مشتق شده چند متد کوچک را بازتعریف کند.
در مواردی که تعداد متدهای abstarct شما زیاد است، احتمالاً شما باید interface تعریف میکردید.
خلاصه:
وراثت کلاس (abstarct یا غیر abstarct) باید برای بیشترین شباهت (ارث بری) استفاده شود و سایر ویژگی های اضافه که هر کلاسی از هر شاخه وراثتی میتواند داشته باشد، باید interface باشند.
در نهایت دقت کنید، همانطور که در بالا به کرات (زورکی!) اشاره کردم تفاوت interface و abstarct مطرح نیست و مهم نیست!
اصلاً abstarct بودن یا نبودن مهم نیست، تفاوت اصلی سر interface و class (وراثت) است!
متاسفم زیاد شد، شاید حوصله نکنید تمام آن را مطالعه کنید ولی احساس کردم کمتر بنویسم نمیتوانم چیزی که در ذهنم است را منتقل کنم.
موفق باشید.
vBulletin , Copyright ©2000-2025, Jelsoft Enterprises Ltd.