کلاس ها و رابط های انتزاعی در همه زبان های برنامه نویسی شی گرا بسیار محبوب هستند. و تقریباً در هر مصاحبه جاوا با حداقل یک سؤال در مورد این موضوع روبرو می شوید. رابط ها به دلیل محبوبیت آنها در بین طراحان نرم افزار بیشتر ذکر می شوند، اما سؤالاتی در مورد کلاس های انتزاعی نیز هر از گاهی مطرح می شود. دومی اغلب از متقاضیان برای موقعیت توسعه دهندگان جوان پرسیده می شود، مثلاً با بیش از دو سال تجربه در توسعه جاوا، در حالی که سؤالات مربوط به رابط ها اغلب در طول مصاحبه با کسانی که تجربه آنها از چهار سال گذشته است، مواجه می شود. آنها معمولاً همراه با سؤالات دیگری در مورد الگوهای طراحی جاوا، مانند الگوهای Decorator یا Factory پرسیده می شوند.
در این مقاله، ما به سوالات متداول در کلاسهای انتزاعی و رابطهایی که در سطوح مختلف مصاحبههای جاوا پرسیده شدهاند، میپردازیم. بسیاری از آنها حتی برای یک برنامه نویس تازه کار جاوا نیز نباید دشوار باشد. اینها عمدتاً سؤالات دانش خالص هستند، اما برخی از آنها، مانند
تفاوت بین کلاس های انتزاعی و رابط ها در جاوا، یا زمان
انتخاب یک کلاس انتزاعی به جای یک رابط ، می تواند بسیار مشکل باشد. ما ده ها سوال جالب در مورد این موضوع را به شما پیشنهاد می کنیم.
اگر تا به حال در مصاحبه ای از شما سؤالی پرسیده شده است یا مجبور شده اید سؤال ارزشمندی در مورد کلاس ها و رابط های انتزاعی بپرسید، اما در این لیست نیست، لطفاً آن را در نظرات به اشتراک بگذارید. |
1. آیا یک کلاس انتزاعی می تواند سازنده در جاوا داشته باشد؟
بله، در یک کلاس انتزاعی در جاوا می توانید سازنده ها را تعریف و تعریف کنید. از آنجایی که ایجاد نمونههایی از کلاسهای انتزاعی غیرممکن است، چنین سازندهای را میتوان تنها در هنگام تشکیل زنجیرهای از سازندهها، یعنی هنگام ایجاد یک نمونه از یک کلاس پیادهسازی خاص فراخوانی کرد. اما تصور کنید که مصاحبه کننده این سوال را بپرسد: اگر به هر حال نتوانید نمونه ای از یک کلاس انتزاعی ایجاد کنید، فایده سازنده چیست؟ نکته این است که هنوز هم می توان از آن برای تنظیم مقادیر اولیه متغیرهای رایج اعلام شده در یک کلاس انتزاعی و استفاده توسط پیاده سازی های مختلف استفاده کرد. حتی اگر سازنده ای را اعلان نکنید، کامپایلر یک سازنده پیش فرض بدون آرگومان را به کلاس abstract اضافه می کند. بدون آن، کلاس فرعی شما کامپایل نخواهد شد زیرا اولین عبارت در هر سازنده یک فراخوانی ضمنی
super()
به سازنده پیشفرض سوپرکلاس در جاوا است.
2. آیا کلاس های انتزاعی در جاوا می توانند رابط ها را پیاده سازی کنند؟ آیا آنها باید همه روش ها را اجرا کنند؟
بله، کلاس های انتزاعی می توانند رابط ها را با استفاده از
implements
. از آنجایی که آنها انتزاعی هستند، نیازی به اجرای همه روش ها ندارند. داشتن یک کلاس پایه انتزاعی و یک رابط برای اعلام نوع یک عمل توصیه شده است. یک مثال یک رابط
java.util.List
و کلاس انتزاعی مربوطه است
java.util.AbstractList
. از آنجایی که
AbstractList
تمام متدهای رایج را پیاده سازی می کند، پیاده سازی های خاص (مانند
LinkedList
و
ArrayList
) لازم نیست همه متدها را پیاده سازی کنند، همانطور که اگر
List
مستقیماً اینترفیس را پیاده سازی کنند، این اتفاق می افتد. این راه حل مزایای استفاده از یک رابط برای اعلام یک نوع را با انعطاف پذیری یک کلاس انتزاعی برای پیاده سازی تمام رفتارهای رایج در یک مکان ترکیب می کند. در کتاب جاشوا بلوخ
«جاوا. برنامه نویسی موثر” یک فصل عالی با موضوع استفاده از رابط ها و کلاس های انتزاعی در جاوا دارد که برای درک بهتر مطالعه آن منطقی است.
3. آیا کلاس انتزاعی می تواند نهایی باشد؟
نه، او نمی تواند. کلمه کلیدی
final
به این معنی است که کلاس در بالای سلسله مراتب است و نمی تواند فرزندان داشته باشد. و یک کلاس انتزاعی بدون وارث یک اسب کروی شکل در خلاء است، زیرا ایجاد یک نمونه غیرممکن است
abstract class
. بنابراین، اگر کلاسی هر دو باشد
abstract
و
final
، پس هیچ نسلی ندارد و نمیتوان آن را نمونهسازی کرد. کامپایلر جاوا اگر کلاس
abstract
و
final
.
4. آیا یک کلاس انتزاعی در جاوا می تواند متدهای ثابت داشته باشد؟
بله، کلاس های انتزاعی می توانند متدهای استاتیک را اعلام و تعریف کنند. فقط لازم است اصول کلی ایجاد متدهای استاتیک در جاوا را رعایت کنید، زیرا در طراحی شی گرا نامطلوب هستند، زیرا نادیده گرفتن روش های استاتیک در جاوا امکان پذیر نیست. متدهای ایستا در یک کلاس انتزاعی بسیار نادر هستند، اما اگر دلایل خوبی برای آن وجود داشته باشد، هیچ چیز مانع استفاده از آنها نمی شود.
5. آیا می توان یک کلاس انتزاعی را نمونه کرد؟
نه، شما نمی توانید این کار را انجام دهید. ماهیت یک کلاس انتزاعی این است که کامل نیست و باید در کلاسهای نوادهاش تکمیل شود. یعنی این کلاس آماده استفاده نیست. به عنوان مثال، ممکن است فاقد اجرای برخی از روش ها باشد. از آنجایی که یک کلاس برای استفاده آماده نیست، شیء آن را نمی توان ایجاد کرد. اما می توانید نمونه هایی از وارثان یک کلاس انتزاعی ایجاد کنید. اگر برنامه ای بخواهد یک کلاس انتزاعی را نمونه سازی کند، کامپایلر جاوا با خطا مواجه می شود.
6. آیا لازم است یک کلاس انتزاعی متدهای انتزاعی داشته باشد؟
خیر، یک کلاس انتزاعی ممکن است هیچ متد انتزاعی نداشته باشد. شما می توانید به سادگی با استفاده از یک کلمه کلیدی
abstract
در اعلان یک کلاس در جاوا چکیده ایجاد کنید. کامپایلر هرگونه محدودیت ساختاری را اعمال خواهد کرد، مانند اجازه ندادن نمونه هایی از این کلاس ایجاد شود. به هر حال، این سوال که آیا باید متدهای انتزاعی در یک کلاس یا رابط انتزاعی وجود داشته باشد، بحث برانگیز است. به نظر من یک کلاس انتزاعی باید متدهای انتزاعی داشته باشد، زیرا این اولین چیزی است که یک برنامه نویس هنگام دیدن یک کلاس انتزاعی به آن فکر می کند. این به خوبی با اصل به حداقل رساندن شگفتی ها مطابقت دارد.
7. تفاوت های کلاس انتزاعی و رابط در جاوا چیست؟
این مهم ترین و یکی از کلاسیک ترین سوالات مصاحبه جاوا است. من نمی توانم شمارش کنم که چند بار این سوال را در مصاحبه های جاوا در همه سطوح دیده ام. چیزی که این سوال را جالب می کند، به ویژه فرصت ارائه مثال برای متقاضی است. پاسخ به سؤالاتی در مورد اصول برنامه نویسی شی گرا، مانند انتزاع، کپسوله سازی، چند شکلی و وراثت، آسان است، اما وقتی صحبت از چنین نکات ظریفی می شود، متقاضیان شغل اغلب گیج می شوند و اولین چیزی را که به ذهنشان خطور می کند، می گویند.
پاسخ به این سوال مستحق یک مقاله جداگانه است (مخصوصاً پس از تغییرات در جاوا 8)، اما به طور خلاصه:
- یک رابط فقط رفتار (روشها) یک شی را توصیف میکند، اما حالتها (فیلدها) را ندارد (به جز
public static final
)، در حالی که یک کلاس انتزاعی میتواند آنها را داشته باشد.
- یک کلاس انتزاعی به ارث می رسد (بسط می یابد)، و یک رابط پیاده سازی می شود (اجرا می شود). ما میتوانیم تنها یک کلاس را به ارث ببریم، اما هر تعداد رابط را که دوست داریم پیادهسازی کنیم. یک اینترفیس می تواند یک رابط/رابط دیگر را گسترش دهد.
- کلاسهای انتزاعی زمانی استفاده میشوند که یک رابطه «is-a» وجود داشته باشد، یعنی کلاس فرعی کلاس انتزاعی پایه را گسترش میدهد و اینترفیسها را میتوان توسط کلاسهای مختلفی پیادهسازی کرد که اصلاً به یکدیگر مرتبط نیستند.
8. چه زمانی منطقی است که یک کلاس انتزاعی را به یک رابط ترجیح دهیم و بالعکس؟
این ادامه سوالات قبلی در مورد کلاس ها و رابط های انتزاعی است. اگر می دانید تفاوت نحوی آنها چیست، پاسخ به این سؤال برای شما مشکلی ایجاد نمی کند، زیرا آنها عامل تعیین کننده در تصمیم گیری هستند. از آنجایی که اضافه کردن یک روش جدید به یک رابط منتشر شده تقریبا غیرممکن است، بهتر است در صورت نیاز بالقوه برای توسعه بیشتر از یک کلاس انتزاعی استفاده کنید. توسعه کلاس های انتزاعی در جاوا آسان تر از توسعه رابط ها است. به همین ترتیب، اگر یک رابط متدهای زیادی داشته باشد و اجرای همه آنها به یک دردسر واقعی تبدیل شود، بهتر است یک کلاس انتزاعی برای پیاده سازی پیش فرض ایجاد کنید. این الگو در بسته مجموعه های جاوا دنبال می شود، کلاس abstract
AbstractList
پیاده سازی پیش فرض را برای
List
.
از کلاس های انتزاعی استفاده کنید اگر:
- شما می خواهید کد را بین چندین کلاس نزدیک به هم به اشتراک بگذارید.
- شما انتظار دارید کلاس هایی که کلاس انتزاعی شما را گسترش می دهند متدها یا فیلدهای مشترک زیادی داشته باشند یا به اصلاح کننده های دسترسی به غیر از
public
(مثلا protected
و private
) نیاز داشته باشند.
- شما می خواهید غیر ایستا یا
не-final
فیلدها را اعلام کنید. این به شما امکان می دهد تا روش هایی را تعریف کنید که می توانند به شیئی که به آن تعلق دارند دسترسی داشته باشند و وضعیت آنها را تغییر دهند.
از رابط ها استفاده کنید اگر:
- شما انتظار دارید کلاس های نامرتبط رابط شما را پیاده سازی کنند. به عنوان مثال، اینترفیس ها
Comparable
و Cloneable
توسط بسیاری از کلاس های غیر مرتبط پیاده سازی می شوند.
- شما می خواهید رفتار یک نوع داده خاص را تعریف کنید، اما برای شما مهم نیست که چه کسی آن را پیاده سازی می کند.
- شما می خواهید از وراثت چند نوع استفاده کنید.
9. متد انتزاعی در جاوا چیست؟
روش انتزاعی روشی بدون بدن است. شما به سادگی یک متد را بدون تعریف آن، با استفاده از یک کلمه کلیدی
abstract
در اعلان متد، اعلام می کنید. تمام روش های اعلام شده در داخل یک رابط در زبان جاوا به طور پیش فرض انتزاعی هستند. در اینجا مثالی از یک متد انتزاعی در جاوا آورده شده است:
public void abstract printVersion();
حال برای پیاده سازی این متد باید کلاس abstract را گسترش دهید و این متد را لغو کنید.
10. آیا یک کلاس انتزاعی در جاوا می تواند حاوی متد باشد main
؟
بله، یک کلاس انتزاعی در جاوا میتواند حاوی یک متد باشد
main
، زیرا فقط یک متد استاتیک دیگر است، و یک کلاس انتزاعی را میتوان با استفاده از متد اجرا کرد
main
، البته تا زمانی که آن را نمونهسازی نکنید. این تمام چیزی است که می خواستم به شما بگویم. و به یاد داشته باشید: کلاسها و رابطهای انتزاعی تصمیمهای کلیدی طراحی در فرآیند تحلیل و طراحی شیگرا هستند و البته اگر میخواهید یک سیستم انعطافپذیر ایجاد کنید، باید با احتیاط مورد استفاده قرار گیرند.
GO TO FULL VERSION