در برنامه نویسی شی گرا، کلاس Abstract (آبسترکت | انتزاعی) روشی برای تعریف «متُدها» (Method) و «متغیرها» (Variable) در کلاس است که شامل متدهای Abstract میشوند. این کلاس یکی از بخشهای مهم یادگیری برنامه نویسی در شی گرایی به حساب میآید و برای فعالیت در این زمینه بهتر است که به خوبی فرا گرفته شود. در این مقاله سعی شده است به طور جامع و به همراه مثالهایی با استفاده از زبانهای برنامه نویسی جاوا و C++ به این سوال پاسخ داده شود که کلاس Abstract چیست و این مفهوم مهم در شی گرایی از همه جهت مورد بررسی قرار بگیرد.
Abstract چیست ؟
انتزاع یا «Abstraction» در شی گرایی فرآیندی است که طی آن تنها اطلاعات مورد نیاز نمایش داده خواهند شد و اطلاعات غیرضروری پنهان میشوند. میتوان گفت که هدف اصلی انتزاع، «پنهان کردن» دادهها به حساب میآید. انتزاع به معنی انتخاب دادههای مناسب از میان گروه زیادی از دادهها، برای نشان دادن اطلاعات مورد نیاز جهت کمک به کاهش پیچیدگی و چالشهای برنامه است. کلاس و متدها هم میتوانند انتزاعی باشند. کلاس انتزاعی نوعی کلاس است که یک یا چند متد انتزاعی در آن تعریف میشود. متد انتزاعی در تعریف متدها نمود پیدا میکند و پیادهسازی متدها شامل آن نمیشود.
انتزاع یکی از چند خصوصیت مهم و اصلی شی گرایی به حساب میآید. به طور کلی شی گرایی در برنامه نویسی حوزهای است که علاوه بر دو مفهوم اساسی «کلاس» (Class) و «شی» (Object)، چهار اصل و خصیصه کلیدی را نیز شامل میشود. این چهار خصوصیت و اصل مهم در شیگرایی در ادامه فهرست شدهاند:
- وراثت یا ارث بری (Inheritance)
- تجرید یا انتزاع (Abstraction)
- پلی مورفیسم یا چند ریختی یا چند شکلی (Polymorphism)
- کپسوله سازی (Encapsulation)
زمانی که یک شی با روش انتزاع داده مدلسازی میشود، مجموعههای یکسانی از دادهها در کاربردهای مختلف قابل استفاده هستند. از جمله این کاربردها میتوان به کلاسهای انتزاعی، رفتارهایی از نوع عام (Generic) و سلسله مراتب برنامه نویسی شی گرا اشاره کرد. متُدهای انتزاعی زمانی استفاده میشوند که بیش از یک «زیرکلاس» (Subclass) وظیفه یکسانی را به روشهای مختلف و از طریق پیادهسازیهای متفاوت انجام میدهند. یک کلاس انتزاعی میتواند هر دو نوع متد یعنی متدهای انتزاعی و متدهای معمولی را شامل شود. در ادامه این مقاله به بررسی دقیقتر کلاس آبسترکت پرداخته شده است.
کلاس Abstract چیست ؟
کلاس انتزاعی (آبسترکت | Abstract) نوعی تعریف از متدها و متغیرهای یک کلاس یا گروهی از «اشیا» (Object) به حساب میآید که در آن یک یا چند «متد انتزاعی» (Abstract Method) تعریف و استفاده شده است. کلاسهای انتزاعی در همه زبانهای برنامه نویسی شی گرا، از جمله ++C، «جاوا» (Java)، #C و VB.NET استفاده میشوند. هم اشیا و هم کلاسها را میتوان انتزاعی کرد؛ به عبارت دیگر، آنها در ویژگیهایی خلاصه خواهند شد که با عملکرد برنامه فعلی مرتبط هستند.
نمونههای منحصربهفردی که از کلاسها حاصل میشوند، همان اشیاء هستند. «اعلان کردن» (Declare) کلاس به صورت انتزاعی به این معنی است که نمیتوان برای آن به طور مستقیم نمونه ایجاد کرد، به عبارت دیگر، شی نمیتواند از مستقیماً از کلاس انتزاعی ایجاد شود. این شیوه یعنی استفاده از کلاسهای آبسترکت باعث میشود بتوان از کدها در برابر استفاده نادرست محافظت کرد. کلاس Abstract به زیرکلاسهایی برای تعریف ویژگیهای مورد نیاز جهت نمونهسازی منحصربهفرد نیاز دارد. کلاسهای انتزاعی در تضاد با «کلاسهای عینی» (Concrete Class) هستند، این کلاسها «نوعی کلاس پیشفرض» (Default Type) در نظر گرفته میشوند.
کلاس عینی، هیچ متد انتزاعی ندارد و میتوان به راحتی نمونهسازی را بر اساس آن انجام داد. استفاده از کلاس Abstract در برنامه نویسی اجباری نیست، اما این مفهوم برای تمیزتر نوشته شدن کدها نسبت به روشهای دیگر و کارآمدتر کردن برنامه نویسی ارائه شده است؛ زیرا در این نوع کلاس دائماً به جزئیات اضافی اشاره نمیشود. کدهای زبان جاوا به دلیل اینکه «غیروابسته به پلتفرم» (Platform-Agnostic) هستند، در فایلهای کلاسی کامپایل میشوند که میتواند توسط هر ماشین مجازی جاوایی تفسیر شود.
پس از دانلود و نصب یک ماشین مجازی جاوا «سازگار» (Compatible) برای پلتفرم سیستم عامل، فایل کلاس به دست آمده میتواند بر روی ماشینهای مختلف اجرا شود. در زبانهای برنامه نویسی، یک کلاس انتزاعی، کلاسی عمومی یا نوعی شی است که به عنوان پایهای برای ایجاد اشیا خاص استفاده میشود. این کلاس با پروتکل آن یا مجموعه عملیاتی که پشتیبانی میکند مطابقت دارد. برای مثال، یک کلاس Abstract در زبان جاوا، «ابَرکلاس» (Super Class)، همان «کلاس پایه» (Base Class) یا «کلاس والدی» (Parental Class) است که قابلیت نمونهسازی ندارد و برای بیان و تعریف ویژگیهای کلی استفاده میشود.
در جاوا نمیتوان شیئی را با استفاده از کلاس انتزاعی جاوا تشکیل داد و تلاش برای نمونهسازی کلاس انتزاعی، تنها منجر به بروز خطای کامپایلر خواهد شد. در زبان جاوا و برخی زبانهای برنامه نویسی دیگر، کلاس Abstract با استفاده از کلمه کلیدی abstract
اعلان میشود. زیرکلاسهای توسعهیافته از یک کلاس انتزاعی، علاوه بر ویژگیهای خاص مربوط به خود، همه ویژگیهای کلاس انتزاعی را هم دارند. کلاس Abstract ویژگیهای کلاس و متدهای پیادهسازی را مشخص میکند، بنابراین میتوان گفت کلاس آبسترکت یک «واسط» (Interface) کامل را تعریف خواهد کرد. در بخش بعدی از مبحث «کلاس Abstract چیست» به بررسی این کلاس در برنامه نویسی شی گرا پرداخته شده است.
کلاس Abstract در برنامه نویسی شی گرا چیست؟
در برنامه نویسی شی گرا، کلاسها نقشهساخت اشیا برای مسائلی هستند که قصد حل آنها در توسعه نرم افزار وجود دارد. کلاسها شامل مجموعهای از ویژگیها (Attribute | Property) و رفتارها (متُدها | Methods) هستند که میتوانند مبتنیبر کلاسهای تعریفشده قبلی باشند. برنامه نویسان از روش «وراثت» یا همان «ارثبری» (Inheritance) برای ایجاد پیادهسازیهای خاص کلاسهای انتزاعی استفاده میکنند. کلاسهایی که به وسیله کلاسهای Abstract ایجاد شدهاند، «کلاس مشتق شده» (Derived Class) یا همان زیرکلاس یا کلاس فرزند نامیده میشوند.
در این حوزه، کلاسهای Abstract در ریشه این سلسله مراتب قرار میگیرند و برای اعمال متدهایی استفاده میشوند که باید در کلاسهای مشتق شده «رونویسی» (Overridden) شوند، بنابراین با این روش از خطاهای ممکن در «زمان اجرا» (Runtime) جلوگیری میشود. کلاسهای Abstract به عنوان الگو برای زیرکلاسهای خود عمل میکنند. برای مثال، زیرکلاس Banyan_Tree
که زیرکلاس کلاس انتزاعی Tree
است، همه ویژگیهای Tree
و همچنین ویژگیهایی را دارد که مختص Banyan_Tree
هستند. درک تفاوت بین کلاس Abstract و واسط برای برنامه نویسان ضروری است.
بخش بعدی از مبحث «کلاس Abstract چیست» پس از معرفی مجموعه دورههای آموزش برنامه نویسی تم آف به بررسی دلیل استفاده از کلاس Abstract در برنامه نویسی اختصاص داده شده است.
معرفی فیلم های آموزش برنامه نویسی تم آف
دورههای وب سایت آموزشی تم آف بر اساس موضوع به صورت مجموعههای آموزشی مختلفی دستهبندی میشوند. یکی از این مجموعههای جامع، مربوط به آموزشهای انواع زبانهای برنامه نویسی گوناگون است. علاقهمندان و دانشجویان میتوانند برای یادگیری بیشتر مفاهیم مختلف برنامه نویسی و همچنین کلاسها و متدهای Abstract در زبانهای برنامه نویسی، از دورههای ارائه شده در این مجموعه آموزشی استفاده کنند. در زمان تدوین این مقاله، مجموعه دورههای برنامه نویسی تم آف حاوی بیش از ۵۲۰ ساعت محتوای ویدیویی و حدود ۶۷ عنوان آموزشی متفاوت است. در ادامه، برخی از دورههای این مجموعه به طور خلاصه معرفی شدهاند:
- فیلم آموزش برنامه نویسی پایتون Python – مقدماتی (طول مدت: ۱۹ ساعت و ۵۳ دقیقه، مدرس: پژمان اقبالی شمس آبادی): در این دوره آموزشی تم آف، زبان برنامه نویسی پایتون از پایهترین مفاهیم تا اصول پیشرفته آن آموزش داده میشود و سعی شده است که همه مباحث مقدماتی مورد نیاز آن ارائه شود. برای مشاهده فیلم آموزش برنامه نویسی پایتون Python – مقدماتی + کلیک کنید.
- فیلم آموزش برنامه نویسی C++ سی پلاس پلاس (طول مدت: ۲۰ ساعت و ۱۴ دقیقه، مدرس: دکتر فرشید شیرافکن): در این تم آف، زبان برنامه نویسیC++ در دو بخش آموزش داده شده است. برای مشاهده فیلم آموزش برنامه نویسی C++ سی پلاس پلاس + کلیک کنید.
- فیلم آموزش برنامه نویسی جاوا Java (طول مدت: 19 ساعت و 19 دقیقه، مدرس: دکتر سید مصطفی کلامی هریس): این دوره آموزشی تم آف به دانشجویان و علاقهمندانی پیشنهاد میشود که قصد یادگیری زبان برنامه نویسی جاوا را به صورت جامع دارند. برای مشاهده فیلم آموزش برنامه نویسی جاوا Java + کلیک کنید.
- فیلم آموزش برنامه نویسی C (طول مدت: ۱۳ ساعت و ۳۰ دقیقه، مدرس: دکتر سید مصطفی کلامی هریس): در این تم آف، زبان برنامه نویسی C همراه با مفاهیم کاربردی آن به همراه مثالهای عملی آموزش داده شده است. برای مشاهده فیلم آموزش برنامه نویسی C + کلیک کنید.
- فیلم آموزش کاربردی برنامه نویسی سی شارپ #C (طول مدت: ۱۳ ساعت و ۵۸ دقیقه، مدرس: مهندس رشید شجاعی): در این دوره آموزشی تم آف، آموزندگان به صورت کاربردی و عملی با زبان سی شارپ و محیطهای Visual Studio و داتنت آشنا میشوند. برای مشاهده فیلم آموزش کاربردی برنامه نویسی سی شارپ #C + کلیک کنید.
- فیلم آموزش برنامه نویسی تایپ اسکریپت TypeScript (طول مدت: ۸ ساعت و ۴۵ دقیقه، مدرس: پوریا کهریزی): این تم آف به علاقهمندانی پیشنهاد شده است که قصد یادگیری زبان برنامه نویسی تایپ اسکریپت را از پایهترین مفاهیم آن دارند. تایپ اسکریپت دارای شباهتهای بسیاری با زبانهای سی شارپ و جاوا اسکریپت است. برای مشاهده فیلم آموزش برنامه نویسی تایپ اسکریپت TypeScript + کلیک کنید.
در ادامه مبحث «کلاس Abstract چیست» و پس از معرفی مختصر برخی از دورههای آموزش برنامه نویسی تم آف، به بررسی دلیل استفاده از کلاس Abstract در برنامه نویسی پرداخته میشود.
چرا از کلاس Abstract در برنامه نویسی استفاده میشود؟
مفهوم کلاسهای آبسترکت بسیار نزدیک به مفهوم ارث بری در برنامه نویسی شی گرا است. وراثت روشی است که با استفاده از آن یک شی خصوصیتهای شی دیگری را کسب میکند یا به ارث میبرد. وراثت از طبقهبندی سلسله مراتبی (Hierarchical Classification) نیز پشتیبانی میکند. ایده دستهبندی سلسله مراتبی (طبقهبندی بالا به پایین) به این صورت است که کلاسهای جدیدی مبتنی بر کلاسهای فعلی ایجاد میشوند. وقتی یک کلاس جدید از کلاس فعلی ارثبری میکند، به این معنی است که میتوان از متُدها و فیلدهای کلاس والد دوباره استفاده کرد.
وراثت بازنمودی از رابطه والد و فرزند به حساب میآید. مثلاً نهنگ عضوی از دستهبندی حیوانات دریایی به حساب میآید. این حیوانات دریایی نیز بخشی از کلاس پستانداران هستند. پستانداران هم زیرکلاس حیوانات محسوب میشوند. از دستهبندی سلسله مراتبی در صورتی استفاده میشود که مثلاً قصد توصیف دسته خاصی از حیوانات مثل پستانداران وجود داشته باشد. در این دستهبندی سلسله مراتبی، دسته یا همان کلاس پستانداران دارای خصوصیتهای (Attribute) جزئیتری مثل دندانها، خونسردی، خونگرمی و سایر موارد نیز هستند.
در واقع پستانداران زیرکلاسی برای کلاس حیوانات به حساب میآیند و دسته حیوانات نیز ابرکلاس دسته پستانداران محسوب میشوند. زیرکلاس، کلاسی است که خصوصیتهای سوپر کلاس را به ارث میبرد. یک سوپر کلاس، کلاسی پایه است که زیرکلاس یا کلاس مشتق شده خصوصیتهای آن را به ارث میبرند. برای بررسی دلیل استفاده از کلاس Abstract در برنامه نویسی بهتر است مثالی برای درک آن شرح داده شود.
مثالی برای واضح تر شدن دلیل استفاده از کلاس آبسترکت در شی گرایی
در این مثال، فرض میشود باید حقوق کارمندان محاسبه شوند و کارمندان به دو دسته پاره وقت و تمام وقت تقسیم میشوند. همانطور که مشخص است، شرکت حقوق این دو دسته را با روشهای مختلفی محاسبه میکند. با این حال، آنها هنوز هم برخی ویژگیها و عملکردهای مشترکی از جمله نام، نام خانوادگی، شماره پرسنلی، حقوق و سایر موارد دارند. حقوق موردی است که باید برای هر کارمند به صورت جداگانه محاسبه شود. بنابراین، باید روشی برای محاسبه حقوق در کلاس پایه کارمندان وجود داشته باشد و هر دو کارمند این روش را به ارث میبرند.
باید به این موضوع توجه داشت که اگرچه یک کارمند در هر صورت دارای حقوقی است، اما برای محاسبه آن باید نوع کارمند اعم از پاره وقت یا تمام وقت مشخص شود. در این مسئله متد محاسبه حقوق باید به صورت Abstract در کلاس کارمند باشد و با توجه به نوع کارمند پیادهسازی متناسبی در زیرکلاسها داشته باشد. در بخش بعدی از مقاله «کلاس Abstract چیست» به بررسی متد Abstract پرداخته شده است.
متد Abstract چیست ؟
متدهای Abstract، متدهایی هستند که بدون پیادهسازی، اعلان میشوند. کلاسهای Abstract شامل متدهای Abstract میشوند. مثلاً یک متد Abstract را میتوان در زبان جاوا به صورت زیر پیادهسازی کرد:
abstract void moveTo(double deltaX, double deltaY);
اگر یک کلاس دارای متد Abstract باشد، این کلاس باید با کلمه کلیدی abstract
اعلان شود؛ شبهکدی از نحوه اعلان این نوع کلاسها در ادامه ارائه شده است:
public abstract class GraphicObject {
// declare fields
// declare nonabstract methods
abstract void draw();
}
هنگامی که یک کلاس Abstract به عنوان زیرکلاس در نظر گرفته میشود، معمولاً این زیرکلاس پیادهسازیهایی را برای همه متدهای انتزاعی در کلاس والد خود ارائه میدهد. با این حال، اگر به این صورت نباشد، زیرکلاس نیز باید به صورت انتزاعی اعلان شود.
نکته مهمی در رابطه با متدها وجود دارد و آن هم این است که متدهایی که در یک واسط یا اینترفیس به صورت پیشفرض یا «ثابت» (Static) اعلان نشدهاند، به طور صریح انتزاعی در نظر گرفته میشوند. بنابراین، اصلاح کنندههای انتزاعی با متدهای واسط استفاده نمیشوند. البته میتوان از آن استفاده کرد ولی غیر ضروری است. در ادامه مثالی از دنیای واقعی برای درک بهتر اینکه Abstract چیست ارائه شده است.
مثال Abstract در برنامه نویسی
در مثال ارائه شده زیر، هدف ایجاد یک درخواستنامه دانشآموزی برای دریافت اطلاعات دانشآموزان است. برخی از اطلاعاتی که جمعآوری میشوند در ادامه فهرست شدهاند:
- نام
- نام خانوادگی
- کلاس
- نشانی
- تاریخ تولد
- نام پدر
- نام مادر
- شماره دانشآموزی
ممکن است همه اطلاعات جمعآوری شده برای پُر کردن این درخواستنامه مورد نیاز نباشند. بنابراین، تنها اطلاعاتی انتخاب میشوند که برای تکمیل درخواستنامه مورد نیاز هستند. از این رو، اطلاعات دانشآموزان از دادههای بزرگ دریافت، حذف و گزینش شدهاند. این فرآیند در مفاهیم شی گرایی به عنوان انتزاع شناخته میشود. در ادامه مثالی از یک کلاس Abstract در زبان برنامه نویسی «جاوا» (Java) ارائه شده است:
//abstract parent class
Abstract class animal {
//abstract method
public abstract void sound ( ) ;
}
Public class lion extends animal {
Public void sound ( ) {
System.out.println (“ roar “ );
}
public Static void main ( String args [ ] ) {
animal obj = new lion ( );
obj. sound ();
}
}
خروجی کدهای فوق کلمه «Roar» به معنی «غرش» است. در کدهای فوق، ابتدا یک کلاس والد به نام animal
تعریف میشود که دارای یک متد Abstract عمومی به نام sound
است. سپس، یک کلاس عمومی در داخل کلاس animal
به نام lion
تعریف میشود که آن را بسط میدهد و زیرکلاس آن به حساب میآید. متد sound
برای کلاس lion
به گونهای تعریف شده است که کلمه Roar را در خروجی چاپ کند.
در آخر نیز در تابع اصلی برنامه یک شی از کلاس lion
با نام obj
ایجاد شده است که با فراخوانی متد sound
روی این شی، عبارت Roar در خروجی چاپ میشود. بخش بعدی از مقاله «کلاس Abstract چیست»، به بررسی دلیل تفاوت کلاس Abstract با واسط اختصاص دارد.
نکته مهم: در کلاس پایه animal
، متد انتزاعی sound
تنها اعلان شده است و هیچ دستورالعمل پیادهسازی برای آن وجود ندارد. در زیر کلاس مشتق شده از این ابر کلاس، یعنی زیر کلاس lion
، نحوه عملکرد متد sound
بهطور خاص تنها برای اشیای نوع lion
تعریف شده است و میتوان این متد را روی اشیای از نوع lion
پیادهسازی و اجرا کرد. در اعلان متد Sound
در زیرکلاس lion
هم مشخص شده که این متد از متد انتزاعی اعلان شده در ابرکلاس انتزاعی animal
بسط داده شده است.
تفاوت کلاس Abstract با واسط چیست؟
کلاسهای Abstract شباهت بسیاری با اینترفیسها یا همان واسطها دارند. امکان نمونهسازی در آنها وجود ندارد و ممکن است حاوی ترکیبی از متدهای اعلان شده یا بدون پیادهسازی باشند. با این حال، با استفاده از کلاسهای Abstract میتوان فیلدهایی را اعلان کرد که ثابت و نهایی نیستند و متدهای عینی خصوصی، «محافظتشده» (Protected) و عمومی را تعریف کرد.
واسط یا همان اینترفیس فقط دارای اعلانهای متد یا متدهای Abstract است و اعضای داده ثابتی دارد. در حالی که، کلاس Abstract ممکن است دارای متد Abstract، اعضای متغیرها و «متدهای عینی» (Concrete Method) هم باشد.
متد Abstract در کلاس مشتق شده باید با یک «تغییر دهنده دسترسی» (Access Modifier)، تعداد و نوع آرگومان را با همان نوع برگشتی کلاس پایه پیادهسازی کند. اشیا از نوع کلاس Abstract را نمیتوان ایجاد کرد؛ زیرا کدها برای نمونهسازی یک شی از نوع کلاس Abstract منجر به خطای کامپایل میشوند.
با استفاده از اینترفیسها، همه فیلدها، به صورت خودکار، عمومی، ثابت و نهایی هستند و همه متدهایی که به عنوان متدهای پیشفرض اعلان یا تعریف میشوند، به صورت عمومی در نظر گرفته شدهاند. علاوه بر این، فقط میتوان یک کلاس را چه انتزاعی باشد و چه نباشد «بسط» (Extend) داد، این در حالی است که میتوان هر تعداد واسط مورد نظر را پیادهسازی کرد.
از آنجایی که فقط زبان برنامه نویسی جاوا از «وراثت واحد» (Single Inheritance) پشتیبانی میکند، در این زبان، یک کلاس میتواند پیادهسازی چندین اینترفیس (واسط) را انجام دهد، اما فقط قابلیت بسط دادن یک کلاس Abstract را دارد. کلاس Abstract حداقل دارای یک متد Abstract است. متد Abstract هیچ کدی در کلاس پایه یا همان والد نخواهد داشت. کدها در کلاسهای مشتق شده آنها اضافه میشوند در ادامه به بررسی شرایط استفاده از اینترفیس و کلاس Abstract پرداخته شده است. ابتدا در بخش بعدی شرایط استفاده از کلاس Abstract ارائه شده است.
شرایط استفاده از کلاس Abstract چیست ؟
از کلاس Abstract در شرایط خاصی در برنامه نویسی میتوان استفاده کرد. برخی از این شرایط در این بخش جمعآوری و فهرست شدهاند:
- زمانی که قصد به اشتراکگذاری کدها بین چندین کلاس مرتبط وجود داشته باشد از کلاس Abstract استفاده میشود.
- انتظار میرود کلاسهایی که کلاس انتزاعی را بسط میدهند، دارای متدها یا فیلدهای مشترک بسیاری باشند، یا به اصلاحکنندههای دسترسی غیر از نوع عمومی آنها مانند خصوصیها یا محافظتشدهها نیاز داشته باشند.
- در زمانهایی که هدف، اعلان فیلدهای غیرثابت یا غیرنهایی است، از کلاس Abstract استفاده میشود. این موضوع امکانی را فراهم میکند که متدهایی تعریف شوند که میتوانند به شیئی دسترسی داشته باشند که به آن تعلق دارند و وضعیت آنها را تغییر دهند.
در بخش بعدی از مبحث «کلاس Abstract چیست» شرایط استفاده از اینترفیس یا همان واسط در برنامه نویسی مورد بررسی قرار گرفته است.
شرایط استفاده از اینترفیس چیست؟
در برخی از شرایط میتوان از اینترفیسها در برنامه نویسی استفاده کرد که در این بخش به بررسی تعدادی از این شرایط پرداخته شده است. آنها در ادامه فهرست شدهاند:
- انتظار میرود که «کلاسهای غیرمرتبط» (Unrelated Class)، پیادهسازی اینترفیس را انجام دهند. برای مثال، اینترفیسهای «Comparable» و «Cloneable» توسط بسیاری از کلاسهای غیرمرتبط پیادهسازی شدهاند.
- زمانی که هدف مشخص کردن رفتار یک داده خاص است از واسط در برنامه نویسی استفاده میشود. با این حال، در این روند نباید نگرانی درباره این موضوع پیش بیاید که چه بخشی این رفتار را پیادهسازی کرده است.
- هنگامی که هدف برنامه نویس استفاده از مزیتهای «وراثت چندگانه» (Multiple Inheritance) است، از اینترفیسها یا واسطها در برنامه نویسی استفاده میشود.
در بخش بعدی از مقاله «کلاس Abstract چیست» به بررسی انواع مثالها در رابطه با کلاس و متد Abstract پرداخته شده است.
نمونه هایی از کلاس Abstract و متدهای آبسترکت
به عنوان نمونههایی برای کلاسهای Abstract میتوان به کلاس «AbstractMap» در «کیت توسعه جاوا» (Java Development Kit | JDK) اشاره کرد که بخشی از مجموعه فریم ورکها به شمار میرود. زیرکلاسهای این کلاس Abstract شامل HashMap ،TreeMap و ConcurrentHashMap میشوند و متدهای بسیاری را از جمله get ،put ،isEmpty ،containKey و containValue را دربرمیگیرد. «HashMap» نمونه دیگری از کلاسی در کیت توسعه جاوا است که چندین واسط را پیادهسازی میکند، برخی از این واسطهای پیادهسازی شده شامل Serializable ،Cloneable و Map
هستند.
با خواندن این فهرست از اینترفیسها، میتوان به این نتیجه رسید که یک نمونه از HashMap صرف نظر از توسعه دهنده یا شرکتی که کلاس آن را پیادهسازی کرده است، میتواند «بازتولید» (Clone) شود. همچنین دارای قابلیت «سریالسازی» (Serializable) است، به عبارت دیگر میتواند به یک «جریان بایت» (Byte Stream) تبدیل شود و دارای عملکرد نقشه نیز است. به علاوه، واسط Map
با متدهای پیشفرض بسیاری از جمله merge
و forEach
بهبود یافته است که کلاسهای قدیمیتری آنها را پیادهسازی کردهاند. بنابراین، نیازی به تعریف نیز ندارند. باید به این نکته توجه داشت که بسیاری از کتابخانههای نرم افزاری هم از کلاسهای Abstract و هم از واسطها استفاده میکنند.
کلاس HashMap چندین واسط را پیادهسازی میکند و همچنین کلاس انتزاعی AbstractMap را بسط میدهد. در ادامه مبحث «کلاس Abstract چیست» به بررسی مثالهایی همراه با کدهای آنها در برخی از زبانهای برنامه نویسی از جمله جاوا پرداخته شده است.
مثال کلاس Abstract در زبان برنامه نویسی جاوا
در برنامههای ترسیم شی گرا، میتوان «دایرهها» (Circle)، «مستطیلها» (Rectangle)، «خطها» (Line)، «منحنیها» (Bezier Curve) و اشیا گرافیکی بسیار دیگری را ترسیم کرد. این اشیا معمولاً دارای حالتهای خاصی از جمله موقعیت، جهت، رنگ خطها و رنگ کامل هر کدام و رفتارهایی از جمله حرکت، چرخش، تغییر اندازه و ترسیم هستند. برخی از این حالتها و رفتارها از جمله موقعیت، رنگ کامل شکل و حرکت، برای همه اشکال گرافیکی یکسان به حساب میآیند. برخی از آنها نیز مانند تغییر اندازه و ترسیم، نیازمند پیادهسازی متفاوتی هستند. همه «اشیا گرافیکی» (GraphicObject) باید بتوانند خود را ترسیم کنند و تغییر اندازه بدهند و فقط روش انجام این کار توسط آنها متفاوت است.
موضوع شرح داده شده، موقعیتی بسیار عالی برای یک سوپرکلاس Abstract به حساب میآید. در این مثال، میتوان از مزایای این شباهتها استفاده کرد و همه اشیای گرافیکی را از یک شی والد Abstract به ارث برد. این شی والد Abstract در تصویر زیر با نام GraphicObject نشان داده شده است و چهار مستطیلی که در زیر آن قرار دارند کلاسهایی هستند که از آن ارث بری میکنند.
برای حل این مثال، ابتدا کلاس انتزاعی GraphicObject برای آماده کردن متغیرهای اعضا و متدهایی که به طور کامل توسط همه زیرکلاسها مشترک هستند از جمله متد «موقعیت فعلی» (Current Position) و «حرکت» (MoveTo) اعلان میشود. همچنین GraphicObject متدهای Abstract را به عنوان متدهایی از جمله «ترسیم» (Draw) یا «تغییر اندازه» (Resize) اعلان میکند که باید توسط همه زیرکلاسها پیادهسازی شوند، اما روش پیادهسازی هر کدام از آنها متفاوت است. کلاس انتزاعی GraphicObject میتواند به صورت زیر نوشته شود:
abstract class GraphicObject {
int x, y;
...
void moveTo(int newX, int newY) {
...
}
abstract void draw();
abstract void resize();
}
هر زیرکلاس غیر Abstract از کلاس GraphicObject مانند کلاس Circle
یا Rectangle
باید پیادهسازیهایی را برای متدهای draw
و resize
ارائه دهند. کدهای پیادهسازی این کلاسها در ادامه مشاهده میشوند:
class Circle extends GraphicObject {
void draw() {
...
}
void resize() {
...
}
}
class Rectangle extends GraphicObject {
void draw() {
...
}
void resize() {
...
}
}
در بخش بعدی از این مقاله به بررسی زمانی پرداخته شده است که یک کلاس Abstract ، واسط یا اینترفیسی را پیادهسازی میکند.
چه زمانی کلاس Abstract یک واسط را پیاده سازی می کند؟
زمانی که یک کلاس قصد پیادهسازی واسطی را دارد تا با همه متدهای واسط، آن را پیادهسازی کند، این مسئله امکانپذیر است؛ با این حال میتوان کلاسی را نیز تعریف کرد که نیازی نباشد همه متدهای اینترفیس را پیادهسازی کند، اما این کلاس حتماً باید به صورت انتزاعی پیادهسازی شود. برای مثال شبهکدهای جاوا برای پیادهسازی این کلاس Abstract در ادامه ارائه شدهاند:
abstract class X implements Y {
// implements all but one method of Y
}
class XX extends X {
// implements the remaining method in Y
}
در کدهای فوق، کلاس X
باید Abstract باشد؛ زیرا متد Y
را به طور کامل پیادهسازی نمیکند. اما کلاس XX
متد Y
را پیادهسازی میکند. در بخش بعدی از این مقاله به بررسی اعضای کلاس پرداخته شده است.
عضو کلاس Abstract چیست ؟
یک کلاس Abstract میتواند دارای فیلدهای «ثابت» ( static
) و متدهای ثابت باشد. همچنین میتوان این عضوهای ثابت را با استفاده از «مرجع کلاس» (Class Reference) مانند سایر کلاسها استفاده کرد. برای مثال متدهای ثابت به صورت زیر تعریف میشوند:
AbstractClass.staticMethod()
در بخش بعدی از مبحث «کلاس Abstract چیست» به بررسی انواع مثالها و روش نوشتن کدهای کلاس Abstract در زبان برنامه نویسی ++C پرداخته شده است.
کلاس Abstract در زبان برنامه نویسی ++C
همانطور که پیش از این نیز به طور جامع مورد بررسی قرار گرفت، کلاس Abstract، کلاسی به حساب میآید که برای استفادههای خاص از کلاس پایه طراحی میشود. کلاس Abstract حداقل شامل یک «تابع مجازی مجرد» (Pure Virtual Function) در برخی از زبانهای برنامه نویسی از جمله ++C است. میتوان این تابع مجازی مجرد را با استفاده از pure specifier (= 0)
هنگام اعلان تابع عضو مجازی در اعلان کلاسها، تعریف کرد. در ادامه، مثالی از کدهایی ارائه شده است که یک کلاس Abstract را در زبان برنامه نویسی ++C تعریف میکنند:
class AB {
public:
virtual void f() = 0;
};
در کدهای فوق، f
یک تابع مجازی مجرد است. تعریف تابع نمیتواند هم یک «مشخصه مجرد» (Pure Specifier) و هم تعریف داشته باشد. برای مثال، کامپایلر امکان پیادهسازی کدهای زیر را نمیدهد و این کدها خطا دریافت میکنند:
struct A {
virtual void g() { } = 0;
};
نمیتوان از یک کلاس Abstract به عنوان نوع پارامتر، نوع بازگشت تابع یا نوع «تبدیل صریح» (Explicit Conversion) استفاده کرد و همچنین یک شی از یک کلاس Abstract قابلیت اعلان شدن ندارد. با این حال، میتوان اشارهگرها و مراجع یک کلاس Abstract را اعلان کرد. مثالی که در ادامه ارائه شده است، این موارد را نشان میدهد:
struct A {
virtual void f() = 0;
};
struct B : A {
virtual void f() { }
};
// Error:
// Class A is an abstract class
// A g();
// Error:
// Class A is an abstract class
// void h(A);
A& i(A&);
int main() {
// Error:
// Class A is an abstract class
// A a;
A* pa;
B b;
// Error:
// Class A is an abstract class
// static_cast(b);
}
در کدهای فوق، کلاس A
یک کلاس Abstract است. کامپایلر امکان اعلان تابع A g()
یا void h(A)
، اعلان شی a و «static cast» شی b را برای نوعی از A
بودن نمیدهد. در این مثال، توابع عضو مجازی به ارث برده میشوند. یک کلاس مشتق شده یا همان کلاس فرزند از یک کلاس پایه یا والد Abstract نیز کلاسی Abstract خواهد بود، مگر اینکه هر تابع مجازی مجرد در کلاس مشتق شده «رونویسی» (Override) شده باشد. در ادامه، کدهای مثال دیگری ارائه شده است:
class AB {
public:
virtual void f() = 0;
};
class D2 : public AB {
void g();
};
int main() {
D2 d;
}
در کدهای فوق، کامپایلر امکان پیادهسازی شی d را نمیدهد؛ زیرا D2
یک کلاس Abstract به حساب میآید. این کلاس خصوصیات تابع مجازی مجرد f()
را از کلاس AB
به ارث میبرد. در این مثال، کامپایلر امکان اعلان شی d
را در صورتی میدهد که تابع D2::f()
تعریف شده باشد. زیرا بر اساس این رونویسی از تابع مجازی مجرد AB::f()
ارث بری میشود. اگر قصد از بین بردن انتزاعی بودن کلاس D2
وجود داشته باشد، باید تابع AB::f()
رونویسی شود. همچنین، باید به این موضوع توجه داشت که میتوان یک کلاس Abstract را از یک کلاس غیر Abstract ایجاد و استخراج کرد. میتوان یک تابع مجازی غیر مجرد را با یک تابع مجازی مجرد رونویسی کرد.
اعضای تابع از یک تابع «سازنده» (Constructor) یا تابع «مخرب» (Destructor) کلاس Abstract فراخوانی میشوند. با این حال، نتایج فراخوانی مستقیم یا غیرمستقیم یک تابع مجازی مجرد از سازنده آن تعریف نشده است. کدهای زیر نشان دهنده این موضوع هستند:
struct A {
A() {
direct();
indirect();
}
virtual void direct() = 0;
virtual void indirect() { direct(); }
};
در کدهای فوق، سازنده پیشفرض A
، تابع مجازی مجرد را به صورت مستقیم با direct()
و به صورت غیرمستقیم با indirect()
فراخوانی میکند.
جمعبندی
با پیشرفت روز افزون انواع زبانهای برنامه نویسی، مشخص است که یادگیری زبانهای جدید شی گرا از جمله جاوا، پایتون، ++C و سایر زبانها کمک بسزایی در مسیر شغلی و علمی افراد و روند پیشرفت فناوری خواهد کرد. به همین دلیل، در این مقاله یادگیری متد و کلاس Abstract به عنوان یکی از رویکردهای مهم شی گرایی در برنامه نویسی مورد بررسی قرار گرفته است.
در مقاله «کلاس Abstract چیست»، سعی شد به طور جامع به همه تعاریف و مفاهیم این رویکرد پرداخته شود. همچنین، همه موارد مرتبط به آن از جمله ارث بری، واسط و تفاوت آنها با متد و کلاس Abstract نیز بررسی شدند. برای درک بهتر متد و کلاس Abstract مثالهایی در زبان برنامه نویسی جاوا و ++C نیز ارائه شد. در نهایت برای درک بهتر برنامه نویسی، شی گرایی و کلاسهای انتزاعی، برخی از دورههای آموزشی تم آف در این مقاله به علاقهمندان و دانشجویان معرفی شدند.