شی گرایی در جاوا چیست؟ — تعریف، مفهوم و تمرین به زبان ساده
در این مقاله، مفاهیم برنامه نویسی شی گرا (Object Oriented Programming | OOP) در زبان جاوا (Java) بررسی میشوند. هدف اصلی شی گرایی، پیادهسازی موجودیتهای دنیای واقعی در برنامه نویسی است. مفاهیم برنامه نویسی شی گرا روشها و متغیرهایی را جهت استفاده مجدد از آنها همراه با سازگاری کامل در برنامه ایجاد میکنند. در شی گرایی به جای تأکید روی توابع، بیشتر تاکید بر دادهها وجود دارد و با آنها به عنوان اشیا برخورد میشود. پرکاربردترین و مهمترین زبانهای برنامه نویسی شی گرا زبان جاوا، «++C»، جاوا اسکریپت (JavaScript)، پایتون (Python)، روبی (Ruby)، پرل (Perl)، اسمال تاک (Smalltalk) و سایر موارد را شامل میشوند. در این مقاله، به بررسی کامل و جامع شی گرایی در جاوا پرداخته شده است.
شی گرایی در برنامه نویسی چیست؟
شی گرایی در برنامه نویسی روشی جهت طراحی برنامهها با استفاده از کلاسها (Class) و اشیا (Object) به حساب میآید. اهمیت شی گرایی در جاوا به گونهای است که این رویکرد برنامه نویسی به عنوان هسته جاوا (Core Of Java) شناخته میشود. شی گرایی اشیا را در برنامه نویسی سازماندهی و واسط (Interface) در جاوا را به خوبی تعریف میکند. این روش به عنوان روشی جهت کنترل دادهها در کدها نیز مورد استفاده قرار میگیرد.
شی گرایی در برنامه نویسی حوزهای است که علاوه بر دو مفهوم اساسی «کلاس» (Class) و «شی» (Object)، چهار اصل و خصیصه کلیدی را نیز شامل میشود. این چهار خصوصیت و اصل مهم در شیگرایی در ادامه فهرست شدهاند:
- وراثت یا ارث بری (Inheritance)
- تجرید یا انتزاع (Abstraction)
- پلی مورفیسم یا چند ریختی یا چند شکلی (Polymorphism)
- کپسوله سازی (Encapsulation)
در این رویکرد، برنامه نویسان، نوع داده، ساختار نوع داده و عملیاتی که روی ساختار داده انجام میشود را تعریف میکنند. بنابراین، علاوه بر کلاسها و اشیا، برای بهرهمندی از مزیتهای شیگرایی در برنامه نویسی، علاوه بر تعریف و استفاده از کلاسها و اشیا، لازم است چهار اصل فوق نیز در برنامه پیادهسازی و نگهداری (Maintain) شوند.
در این بخش به شی گرایی در برنامه نویسی و تعاریف آن پرداخته شد. حال در ادامه مقاله، وارد شی گرایی در زبان برنامه نویسی جاوا شده و مفاهیم و مباحث مختلف آن همراه با ارائه مثال آموزش داده شده است.
شی گرایی در جاوا چیست ؟
برنامه نویسی شی گرا، مفهومی در زبان جاوا جهت بهبود خوانایی (Readability) و قابلیت استفاده مجدد (Reusability) از کدها به وسیله تعریف کارآمد برنامه به حساب میآید. اصول اساسی شی گرایی در این زبان برنامه نویسی نیز مانند سایر زبانها، خصیصههای تجرید یا انتزاع، کپسوله سازی، وراثت یا ارث بری، چند ریختی یا پلی مورفیسم در جاوا و سایر موارد را شامل میشوند.
همانطور که بیان شد، هدف از تبیین این اصول، پیادهسازی موجودیتهای دنیای واقعی در برنامهها است. در بخشهای بعدی به بررسی هر یک از مفاهیم و اصول شی گرایی در جاوا پرداخته شده است. ابتدا برای شرح شی گرای در جاوا به این سوال مهم پاسخ داده شده است که شی در جاوا چیست؟
شی در جاوا چیست ؟
اشیا همیشه به عنوان اعضا یک کلاس در نظر گرفته میشوند. معمولاً اشیا در زبان جاوا یا هر زبان برنامه نویسی دیگری در چارچوب کلاسها ایجاد میشوند و دارای حالت و رفتار هستند. اشیا از انواع داده انتزاعی به حساب میآیند؛ برای مثال، رفتار اشیا توسط مجموعهای از مقادیر و عملکردها (متدها) تعریف میشوند. آنها معمولاً بر اساس اشیا در دنیای واقعی مثل موجودیتهای واقعی به وجود میآیند. بنابراین، به اشیا موجودیتهای زمان اجرا گفته میشود. از این رو، آنها موجودیتهایی مستقل، شامل متُدها (Method) و ویژگیها (Property) جهت ایجاد دادههای مفید هستند.
اشیا میتوانند به صورت فیزیکی و منطقی تعریف شوند. آنها شامل آدرس هستند و مقداری از فضای حافظه را اشغال میکنند. برای مثال در دنیای واقعی میتوان گفت که سگ، صندلی، درخت و سایر موارد شی به حساب میآیند. زمانی که حیوانات به عنوان شی در نظر گرفته میشوند، پس میتوان گفت که دارای حالتهایی مانند رنگ، اسم، نژاد و سایر موارد هستند (همان خصوصیتهای یا Propertyها). همچنین، این اشیا رفتارهایی از جمله خوردن، تکان دادن دُم و سایر موارد را هم از خود بروز میدهند که به نوعی همان متدها یا عملکردهای آنها به حساب میآیند.
مثالی برای ایجاد شی در جاوا
برای مثال در کدهای زیر، کلاسی به نام «Mybook» در زبان برنامه نویسی جاوا تعریف و سپس شیئی از این کلاس با نام Myobj در داخل این کلاس ایجاد شده است.
Public class Mybook {
int x=10;
Public static void main (String args []) {
Mybook Myobj= new Mybook ();
System.out.println(MyObj.x);
}
}
برای ایجاد و تعریف این کلاس از کلمات کلیدی Public و Class استفاده شده است. پس از آن هم نام کلاس نوشته میشود. کلمه کلیدی Public نوع دسترسی اعضای کلاس را تعیین میکند؛ یعنی نوع دسترسی در کلاس Mybook عمومی است. اعضای Public (عمومی) برای تمام دیگر کلاسها قابل مشاهده هستند. این یعنی هر کلاس دیگری میتواند به یک فیلد یا متد عمومی دسترسی داشته باشد. خط کد زیر، مربوط به ایجاد شی Myobj در کدهای فوق است:
Mybook Myobj= new Mybook ();
خط کد زیر هم جهت برگرداندن مقدار x از شی Myobj استفاده میشود:
System.out.println(Myobj.x);
همچنین میتوان در یک کلاس واحد چند شی تعریف کرد. علاوه بر این در جاوا امکان دسترسی به شی تعریف شده در یک کلاس از کلاس دیگر هم وجود دارد. این روش جهت سازماندهی بهتر کلاسها انجام میشود. همیشه باید به این موضوع توجه داشت که نام فایل جاوا و نام کلاس در زبان جاوا ثابت است. در ادامه مثالی برای تعریف چند شی در یک کلاس ارائه میشود.
مثالی برای ایجاد چند شی در یک کلاس جاوا
مثال زیر نشان میدهد که چطور میتوان چند شی را در یک کلاس جاوا ایجاد کرد و در کلاسهای دیگر نیز به آن دسترسی داشت:
- برای این مثال، ابتدا کدهای زیر در فایلی به نام «Mybook.java» ذخیره میشوند.
Public class Mybook {
int x=10;
int y=8;
}
- کدهای زیر نیز در فایل «Count.java» نوشته شدهاند:
Class Count {
Public static void main (String [] args)
{
Mybook myobj1 = new myobj1();
Mybook myobj2 = new myobj2();
System.out.println (myobj1.x);
System.out.println (myobj2.y);
}
}
در این مثال، دو شی با نامهای myobj1 و myobj2 از کلاس عمومی Mybook در کلاس «Count» ایجاد شده است. زمانی که این کدها اجرا میشوند، در خروجی عدد ۱۰ و ۸ به ترتیب چاپ خواهند شد. در ادامه این مقاله به بررسی چیستی کلاس در زبان جاوا پرداخته شده است.
مفهوم کلاس در شی گرایی در جاوا چیست ؟
کلاسها را میتوان به عنوان سازندههایی (Constructor) برای ایجاد اشیا در نظر گرفت. به عبارت دیگر، به مجموعهای از اشیا دارای خصوصیات و رفتار یکسان کلاس گفته میشود. کلاسها کمیتهایی منطقی هستند و فضایی را در حافظه اشغال نمیکنند. در واقع، کلاس قالبی برای ساخت اشیا به حساب میآید.
کلاسها دارای اعضای گوناگونی هستند و از جمله آنها میتوان «فیلدها»، «متُدها» و «سازندهها» را نام برد. کلاسها در جاوا هم دارای آغازگرهای (Initializer) ایستا (استاتیک) و هم دارای آغازگرهای وهلهای (Instance) هستند. به هر شی ساخته شده در یک کلاس، یک وهله (نمونه) از آن کلاس گفته میشود.
اجزای کلاس در شی گرایی در جاوا چه هستند؟
اعلان کلاس در جاوا (Class Declaration) یا همان تعریف و ایجاد کلاس در جاوا به ترتیب شامل اجزای زیر است:
- تعیین کننده سطح دسترسی (Access Modifiers): این جزء در اعلان کلاس در جاوا میتواند به صورت دسترسی عمومی یا دسترسی پیشفرض باشد.
- نام کلاس: حرف اول نام کلاس در جاوا باید به صورت حروف بزرگ باشد.
- سوپر کلاس (ابَرکلاس | Superclass): یک کلاس (زیرکلاس) تنها میةواند یک والد داشته باشد و از آن بسط داده شود.
- واسطها (Interface): یک کلاس میتواند بیش از یک واسط را پیادهسازی کند.
- بدنه کلاس: بدنه کلاس در جاوا بین دو علامت آکولاد ({ }) قرار میگیرد و احاطه میشود.
از کلمه کلیدی «class» برای ایجاد یک کلاس در جاوا استفاده میشود. شبه کد کلی تعریف یک کلاس در زبان جاوا به صورت زیر است:
class classname {
type instance variable 1;
type instance variable 2;
.
.
.
type instance variable n;
type methodname 1 (parameter list) {
// بدنه متد
}
type methodname 2 (parameter list) {
// بدنه متد
}
type methodnamen (parameter list) {
// بدنه متد
}
}
به متغیرها و دادههایی که در یک کلاس تعریف میشوند، متغیرهای نمونه (متغیرهای وهله) گفته میشود. در بدنه متدها همیشه کدهایی وجود دارند. بنابراین، متدها و متغیرهایی که در یک کلاس تعریف شدهاند، «اعضای» آن کلاس خطاب میشوند. در ادامه به شرح مفهوم تجرید یا انتزاع از مبحث شی گرایی دار جاوا پرداخته شده است.
- مقاله پیشنهادی: متدهای جاوا — به زبان ساده
مفهوم انتزاع در شی گرایی در جاوا چیست ؟
انتزاع یا همان Abstraction در شی گرایی جاوا فرآیندی است که طی آن تنها اطلاعات مورد نیاز نمایش داده میشوند و اطلاعات غیرضروری پنهان خواهند شد. میتوان گفت که هدف اصلی انتزاع، «پنهان کردن» دادهها به حساب میآید. انتزاع به معنی انتخاب دادههای مناسب از میان گروه زیادی از دادهها، برای نشان دادن اطلاعات مورد نیاز جهت کمک به کاهش پیچیدگی و چالشهای برنامه است. کلاس و متدها هم میتوانند انتزاعی باشند. کلاس انتزاعی نوعی کلاس است که یک یا چند متد انتزاعی در آن تعریف میشود. متد انتزاعی دارای تعریف متدهاست و پیادهسازی متدها شامل آن نمیشود.
زمانی که یک شی با روش انتزاع داده مدل سازی میشود، مجموعههای یکسانی از دادهها در کاربردهای گوناگون قابل استفاده هستند. از جمله این کاربردها میتوان به کلاسهای انتزاعی، رفتارهایی از نوع عام (Generic) و سلسله مراتب برنامه نویسی شی گرا اشاره کرد. متُدهای انتزاعی زمانی استفاده میشوند که بیش از یک زیر کلاس وظیفه یکسانی را به روشهای مختلف و با از طریق پیادهسازیهای گوناگون انجام میدهند. یک کلاس انتزاعی میتواند هر دو نوع متد یعنی متدهای انتزاعی و متدهای معمولی را شامل شود. در ادامه این بخش به ارائه مثالی پیرامون انتزاع در شی گرایی جاوا پرداخته شده است.
مثال انتزاع در جاوا
در این مثال، هدف ایجاد یک درخواستنامه دانشآموزی برای دریافت اطلاعات دانشآموزان است. برخی از اطلاعاتی که جمعآوری میشوند در ادامه فهرست شدهاند:
- نام
- کلاس
- نشانی
- تاریخ تولد
- نام پدر
- نام مادر
- سایر موارد
ممکن است همه اطلاعات جمعآوری شده برای پُر کردن این درخواستنامه مورد نیاز نباشند. بنابراین، تنها اطلاعاتی انتخاب میشوند که برای تکمیل درخواستنامه مورد نیاز هستند. از این رو، اطلاعات دانشآموز از دادههای بزرگ دریافت، حذف و گزینش شدهاند. این فرآیند در مفاهیم شی گرایی به عنوان انتزاع شناخته میشود. در ادامه مثالی از یک کلاس انتزاعی آمده است:
//کلاس والد انتزاعی
Abstract class Animal {
//متد انتزاعی
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 تعریف میشود که دارای یک متد انتزاعی عمومی به نام sound است. سپس، یک کلاس عمومی در داخل کلاس Animal به نام Lion تعریف شده است که آن را بسط میدهد و زیر کلاس آن به حساب میآید.
متد sound برای کلاس Lion به گونهای تعریف شده است که کلمه Roar را در خروجی چاپ میکند. در آخر نیز در تابع اصلی برنامه یک شی از کلاس Lion با نام obj ایجاد شده است که با فراخوانی متد sound روی این شی، عبارت Roar در خروجی چاپ میشود. ادامه این مقاله به بررسی چیستی وراثت یا ارث بری در شی گرایی جاوا اختصاص داده شده است.
مفهوم وراثت در شی گرایی در جاوا چیست ؟
وراثت روشی است که با استفاده از آن یک شی خصوصیتهای (خصلتهای) شی دیگری را کسب میکند یا به ارث میبرد. وراثت از طبقهبندی سلسله مراتبی (Hierarchical Classification) نیز پشتیبانی میکند.
ایده دستهبندی سلسله مراتبی (طبقهبندی بالا به پایین) به این صورت است که کلاسهای جدیدی مبتنی بر کلاسهای فعلی ایجاد میشوند.
وقتی یک کلاس جدید از کلاس فعلی ارثبری میکند، میتوان از متُدها و فیلدهای کلاس والد دوباره استفاده کرد. وراثت بازنمودی از رابطه والد و فرزند به حساب میآید. مثلاً یک وال عضوی از دستهبندی حیوانات دریایی به حساب میآید. حیوانات دریایی نیز بخشی از کلاس پستانداران هستند.
پستانداران هم زیرکلاس حیوانات محسوب میشوند. از دستهبندی سلسله مراتبی که همان دستهبندی بالا به پایین است در صورتی استفاده میشود که مثلاً قصد توصیف دسته خاصی از حیوانات مثل پستانداران وجود داشته باشد. در این دستهبندی سلسله مراتبی، دسته یا همان کلاس پستانداران دارای خصوصیتهای (Attribute) جزئیتری مثل دندانها، خونسردی، خونگرمی و سایر موارد هستند.
در واقع پستانداران زیرکلاسی (Subclass) برای کلاس حیوانات به حساب میآیند و دسته حیوانات نیز ابرکلاس (Superclass) دسته پستانداران محسوب میشوند. زیرکلاس کلاسی است که خصوصیتهای سوپرکلاس را به ارث میبرد. به زیرکلاس «کلاس مشتق شده» (Derrived Class) هم میگویند. یک سوپر کلاس کلاسی پایه (Base Class) یا کلاس والد (Parental Class) است که زیرکلاس خصوصیتهای آن را به ارث میبرد. برای اینکه یک کلاس در جاوا از کلاس دیگری ارثبری کند، از کلمه کلیدی «extend» استفاده میشود.
در مبحث شی گرایی زبانهای برنامه نویسی شی گرا، پنج نوع وراثت به صورت زیر وجود دارند:
- منفرد (Single Level)
- چند سطحی (Multilevel)
- چندتایی (Multiple)
- ترکیبی (Hybrid)
- سلسله مراتبی (Hierarchical Level)
در ادامه این مقاله به بررسی انواع وراثت در جاوا پرداخته و ابتدا وراثت منفرد شرح داده شده است.
وراثت منفرد شی گرایی در جاوا
در این نوع از وراثت، یک کلاس مشتق شده خصوصیات وراثتی خود را از یک کلاس والد به ارث میبرد. این روش امکان استفاده مجدد از کدها را فراهم و همچنین ویژگیهای جدیدی نیز به کدها اضافه میشوند.
در کدهای زیر، کلاس «b» ویژگیهایش را از کلاس «a» به ارث میبرد. a یک کلاس پایه یا والد است و کلاس b یک کلاس مشتق شده به حساب میآید.
Class a {
…
}
Class b extends class a {
…
}
در ادامه به بررسی وراثت چند سطحی در زبان برنامه نویسی جاوا پرداخته میشود.
وراثت چند سطحی شی گرایی در جاوا
در این نوع از وراثت در جاوا، یک کلاس از کلاس دیگری ارث بری میکند که آن کلاس دیگر نیز مجدداً از یک کلاس متفاوت دیگر ارث میبرد. یعنی این کلاس بیش از یک کلاس والد دارد؛ به همین دلیل به آن وراثت چند سطحی میگویند. سینتکس (نحو) وراثت چندسطحی در جاوا به صورت زیر است:
Class a {
….
}
Class b extends class a {
….
}
Class c extends class b {
…
}
در بخش بعدی مقاله، وراثت سلسله مراتبی در جاوا شرح داده شده است.
وراثت سلسله مراتبی در جاوا
در این نوع از وراثت، یک کلاس والد دارای چند کلاس مشتق شده یا همان زیر کلاس است، به عبارت دیگر چندین کلاس فرزند یک کلاس والد دارند. سینتکس وراثت سلسله مراتبی در جاوا به صورت زیر است:
Class a {
…
}
Class b extends class a {
..
}
Class c extends class a {
..
}
بخش بعدی مقاله به وراثت ترکیبی در جاوا اختصاص داده میشود.
وراثت ترکیبی در جاوا
این نوع وراثت با ترکیب وراثت چندتایی و وراثت چند سطحی به دست میآید. باید به این نکته توجه داشت که در زبان جاوا وراثت چندتایی پشتیبانی نمیشود، زیرا این نوع وراثت در جاوا باعث ایجاد ابهام میشود. لذا این نوع وراثت فقط از طریق واسطها قابل دستیابی است. به فرض کلاس a، یک کلاس والد یا پایه برای کلاس b و c در نظر گرفته میشود و به همین ترتیب کلاس b و c، کلاس والد یا پایه برای کلاس d هستند. کلاس b و c، کلاسهای مشتق شده یا فرزند کلاس a به حساب میآیند و کلاس d، کلاس فرزند یا مشتق شده برای کلاسهای b و c است.
در برنامه زیر یک سوپر کلاس به نام «Add» و یک زیر کلاس به نام «Sub» ساخته میشود. از کلمه کلیدی extend برای ایجاد زیر کلاس Sub استفاده شده است.
// یک مثال ساده از وراثت در جاوا
// ایجاد یک سوپر کلاس
Class Add {
int my;
int by;
void setmyby (int xy, int hy) {
my=xy;
by=hy;
}
}
// ایجاد یک زیر کلاس
class b extends add {
int total;
void sum () {
public Static void main (String args [ ] ) {
b subOb= new b ( );
subOb. Setmyby (10, 12);
subOb. Sum ( ) ;
System.out.println(“total =” + subOb. Total);
}
}
با اجرای کدهای بالا «total = 22» در خروجی چاپ میشود. بدین ترتیب، شرح مبحث وراثت در جاوا جهت یادگیری شی گرایی در جاوا به اتمام رسید و در بخش بعدی مقاله به بررسی پلی مورفیسم (Polymorphism) یا چند ریختی در جاوا پرداخته شده است.
پلی مورفیسم در شی گرایی در جاوا چیست ؟
پلی مورفیسم (چند ریختی | چند شکلی) به وجود شکلهای (فُرمهای) بسیار گفته میشود. یا میتوان گفت پُلی مورفیسم پردازشی به حساب میآید که یک عمل واحد را به روشهای گوناگونی انجام میدهد. پلی مورفیسم در جاوا جهت بالا بردن خوانایی و استفاده مجدد از دادهها به کار گرفته میشود. همانطور که در دنیای واقعی یک شخص میتواند طبق وظایفش در موقعیتهای گوناگون، جایگاه متفاوتی داشته باشد.
مانند جایگاه یک زن در برابر فرزندش به عنوان مادر و در محیط کار به عنوان کارمند، در پلی مورفیسم نیز یک وظیفه طبق جایگاه و رفتار آن با روشهای مختلف تعریف میشود. چندریختی زمانی اتفاق میافتد که تعداد زیادی کلاس از طریق ارث بری با یکدیگر مرتبط هستند. چند ریختی شامل دو نوع متفاوت زیر است:
- چند ریختی استاتیک (Static Polymorphism) یا چند ریختی زمان کامپایل (Compile Time Polymorphism)
- چند ریختی پویا (Dynamic Polymorphism) یا چند ریختی زمان اجرا (Runtime Polymorphism)
به طور کلی، با استفاده از دو روش زیر پلی مورفیسم انجام میگیرد:
- روش اضافه بار (Overloading)
- روش رونویسی کردن (Overriding)
یک مثال در چند ریختی زمان کامپایل هنگامی است که یک متد ایستا (ثابت) در زبان جاوا بارگذاری (Overload) شود. چند ریختی زمان اجرا، ارسال متد پویا (Dynamic Method Dispatch) نیز نامیده میشود. در چند ریختی پویا، فراخوانی یک متد رونویسی (Override) شده است و به جای زمان کامپایل در زمان اجرا انجام میشود. در پلی مورفیسم زمان اجرا، فراخوانی روش «Override» همیشه از طریق متغیر مرجع (Reference Variable) انجام میشود. مفهوم پلی مورفیسم معمولاً به عنوان یک واسط، با چند متد ابراز میشود. این شیوه با ایجاد امکان استفاده از یک واسط به عنوان کلاس کلی عملکرد، پیچیدگی را کاهش میدهد.
مثالی برای چندریختی در شی گرایی جاوا
در ادامه، مثالی برای چندریختی در جاوا آمده است:
public class Bird {
…
Public void sound ( ) {
System.out.println ( “ birds sounds “ );
}
}
public class pigeon extends Bird {
…
@override
public void sound ( ) {
System.out.println( “ cooing ” ) ;
}
}
public class sparrow extends Bird ( ) {
….
@override
Public void sound ( ){
System.out.println( “ chip ” ) ;
}
}
در کدهای فوق، عملکرد مشترک () sound قابل ملاحظه است، اما راههای متفاوتی برای انجام عمل یکسان وجود دارد و این مثال یکی از نمونههایی است که مفهوم پلی مورفیسم را نشان میدهد. در ادامه به بررسی مفهوم پلی مورفیسم زمان کامپایل در زبان برنامه نویسی جاوا پرداخته شده است.
پلی مورفیسم زمان کامپایل در شی گرایی جاوا چیست؟
پلی مورفیسم زمان کامپایل به عنوان پلی مورفیسم ایستا (ثابت) نیز شناخته میشود. Resolve کردن این نوع از چندریختی در زمان کامپایل از طریق سربارگذاری متد (Method Overloading) انجام میشود. در بخش بعدی به مفهوم پلی مورفیسم زمان اجرا در زبان جاوا پرداخته شده است.
پلی مورفیسم زمان اجرا در شی گرایی جاوا چیست؟
پلی مورفیسم زمان اجرا در جاوا با نام مقیدسازی پویا (Dynamic Binding) نیز معرفی شده است. این نوع از پلی مورفیسم جهت فراخوانی یک متد رونویسی شده (overridden) استفاده میشود که به صورت پویا به جای زمان کامپایل، در زمان اجرا Resolve میشود. در بخش بعدی مقاله «شی گرایی در جاوا چیست» به شرح مفهوم کپسوله سازی پرداخته شده است. در مجله تم آف یک مقاله با موضوع چندریختی در جاوا هم منتشر شده است که مطالعه آن نیز برای آشنایی با اصل چندریختی در جاوا به علاقهمندان پیشنهاد میشود:
- مقاله پیشنهادی: پلی مورفیسم در جاوا چیست ؟ — آموزش چند ریختی از صفر تا صد
کپسوله سازی در شی گرایی در جاوا چیست ؟
کپسوله سازی یکی از اصول مهم در مفاهیم برنامه نویسی شی گرا به حساب میآید. این فرآیند با متصل کردن دادهها و کدها به یکدیگر و ایجاد یک واحد منفرد، امنیت آنها را تأمین و از سوءاستفاده و دخالت عوامل خارجی جلوگیری میکند. این روش باعث میشود متدهای موجود در هر کلاس فقط به دادههای همان کلاس دسترسی داشته باشند و متدهای کلاسهای دیگر به دادههای کلاس مورد نظر دسترسی ندارند.
دادههای کلاس کپسوله شده از دسترس دیگر کلاسها مخفی میشوند و آنها به این دادهها دسترسی نخواهند داشت. از این رو، به این مفهوم «پنهانسازی دادهها» (Data Hiding) نیز گفته میشود.
کپسوله سازی در جاوا به عنوان یک پوشش محافظ (Protective Wrapper) عمل میکند که با تعبیه آن در شی گرایی از دسترسی افراد خارجی به کدها و دادهها جلوگیری میشود. این روش از طریق یک واسط تعریف میشود. کپسوله سازی با استفاده از اعلان متغیرها به صورت خصوصی و ایجاد متدهای تنظیم کننده (Setter) و گیرنده (Getter) جهت تغییر و نمایش مقادیر متغیرها به دست میآید.
در این روش، فیلد کلاسها به صورت «فقط خواندنی» (Read Only) و «فقط نوشتنی» (Write Only) ایجاد میشوند. کپسوله سازی قابلیت استفاده مجدد از دادهها را افزایش میدهد و استفاده از کدهای آن، جهت تست یونیت یا واحد (Unit Testing) آسان است. مثال زیر جهت درک بهتر مفهوم کپسوله سازی ارائه میشود:
class animal {
// فیلد خصوصی
private int age;
// (Getter) متد گیرنده
Public int getage ( ) {
return age;
}
// (Setter) متد تنظیم کننده
public void setAge ( int age ) {
this. Age = age;
}
}
class Main {
public static void main (String args []);
// ایجاد یک شی از شخص
Animal a1= new Animal ();
// تغییر سن با استفاده از متد تنظیم کننده
A1. setAge (12);
// دسترسی به سن با استفاده از متد گیرنده
System.out.println(“ animal age is ” + a1. getage ( ) );
}
}
خروجی کدهای فوق «Animal age is 12» است. در این مثال، یک فیلد خصوصی به نام «age» ایجاد میشود که فقط در این کلاس اجازه دسترسی به آن وجود دارد. جهت دسترسی به age از متدهای عمومی تنظیم کننده و گیرنده استفاده میشود. خصوصی کردن age دسترسیهای غیر مجاز بیرون از کلاس را محدود میکند. به همین دلیل به این روش پنهان کردن دادهها نیز گفته میشود.
وابستگی در شی گرایی در جاوا
وابستگی (همبندی | اتصال | جفت شدگی | Coupling) در جاوا به رابطه بین دو کلاس گفته میشود. این موضوع نشان دهنده میزان آگاهی یک شی یا کلاس و ارتباط آن با دیگر کلاسها است.
به عبارت دیگر، میتوان گفت که اگر یک کلاس خصوصیتها یا رفتارش را تغییر دهد، این موضوع روی کلاسهای وابسته به آن نیز تأثیر میگذارد. البته این تغییرات بستگی به سطح وابستگی بین دو کلاس دارد. دو نوع اتصال در جاوا وجود دارد:
- وابستگی سخت (Tight Coupling)
- وابستگی سست (Loose Coupling)
در ادامه این بخش به بررسی این دو نوع اتصال پرداخته میشود و ابتدا اتصال سخت معرفی شده است.
وابستگی سخت در جاوا چیست؟
اگر دو کلاس به صورت قوی با یکدیگر ارتباط برقرار کنند به معنی وجود وابستگی و اتصال قوی بین آنها است. در ادامه مثالی از کدهای متناسب با تعریف این مفهوم در برنامه نویسی جاوا مشاهده میشود:
public class College{
public void status() {
System.out.println("College is open today");
}
}
public class Student{
College obj = new College();
public void goToCollege() {
obj.status();
}
}
در کدهای فوق، کلاس «student» به کلاس «college» وابسته است. به عبارت دیگر، هر تغییری در کلاس college نیاز به تغییر در کلاس student نیز دارد. در این مثال کلاس student و college با یکدیگر در جفت شدگی سخت هستند. در ادامه به بررسی وابستگی سست پرداخته شده است.
وابستگی سست در جاوا چیست؟
اگر یک کلاس به وسیله اتصال ضعیف با کلاس دیگر در تعامل و ارتباط باشد، یعنی در وابستگی سست با آن کلاس است. معمولاً در برنامه نویسی و شی گرایی اتصال سست به اتصال سخت ترجیح داده میشود.
یک کلاس با استفاده از واسطها میتواند به این مهم دست یابد. در ادامه مثالی جهت درک بهتر اتصال سست ارائه شده است:
public interface College{
void status();
}
class CollegeStatus1 implements College{
public void status() {
System.out.println("College is open monday to friday");
}
}
class CollegeStatus2 implements College{
public void status() {
System.out.println("College is open on saturday");
}
}
public class Student{
College obj = new CollegeStatus1();
public void goToCollege() {
obj.status();
}
}
در مثال فوق، کلاس «CollegeStatus1» و کلاس «CollegeStatus2» در اتصال سست با یکدیگر هستند. در این مثال، کلاس student به طور مستقیم یا سخت با دو کلاس CollegeStatus1 و CollegeStatus2 اتصال ندارد. با اعمال ساز و کار تزریق وابستگی، این امکان به کلاس student داده میشود تا با هر کلاس collegeی ارتباط برقرار کند که واسط college را پیادهسازی میکند.
به این نوع از ارتباطات، اتصال سست گفته میشود. به علاوه، میتوان این تعریف را به این صورت بیان کرد که از کلاس CollegeStatus2 هر زمانی استفاده خواهد شد که کالج در روز شنبه باز باشد. در ادامه مطلب «شی گرایی در جاوا چیست»، انسجام در جاوا ( Cohesion in Java) در بخش بعدی شرح داده میشود.
انسجام در جاوا
انسجام ساختاری یا پیوستگی (Cohesion) در جاوا نشان میدهد که چگونه متدها و ویژگیهای یک کلاس بهطور معنادار و قوی با یکدیگر مرتبط هستند و تا چه حد در انجام یک وظیفه تعریف شده برای سیستم متمرکز به حساب میآیند.
از روش انسجام ساختاری جهت نشان دادن درجه مسئولیت واحد و تمرکز در کلاسها استفاده میشود. دو نوع انسجام در جاوا وجود دارد:
- انسجام قوی (High Cohesion)
- انسجام ضعیف (Low Cohesion)
کلاسهای منسجمتر برای قابلیت استفاده مجدد از کدها مناسب هستند. نگهداری و حفظ کلاسهایی که انسجام کمتری دارند، دشوار است زیرا رابطه منطقی کمتری بین روشها و ویژگیهای آنها جود دارد. در برنامه نویسی شی گرا بهتر است همیشه کلاسهایی با انسجام بالا جهت تمرکز روی وظایف وجود داشته باشند. در ادامه این بخش به تعریف انسجام ضعیف در جاوا پرداخته شده است.
انسجام ضعیف در جاوا چیست؟
در کدهایی که در این بخش ارائه شدهاند، یک کلاس به نام «Book» وجود دارد. این کلاس از انسجام کمی برخوردار است زیرا شامل ویژگیها و متدهایی با درجه تمرکز و استقلال کم برای کلاس میشود.
این کلاس باید دارای اطلاعاتی مرتبط با کتاب باشد. از این رو، داشتن متدهایی مانند نام و سن شخص، انسجام این کلاس را کاهش میدهد.
class Book{
int price = 299; // ویژگیهای مرتبط با کلاس کتاب
String name = "Sam"; // ویژگیهای غیر مرتبط با کلاس کتاب
// متدهای مرتبط با کلاس کتاب
public String author(String name) {
return name;
}
public String title(String subject) {
return subject;
}
public int id(int number) {
return number;
}
// متدهای غیر مرتبط با کلاس کتاب
public int age(int age) {
return age;
}
}
در ادامه این بخش به بررسی روش انسجام قوی پرداخته شده است.
انسجام قوی در شی گرایی در جاوا چیست ؟
وقتی که کلاس از یک هدف و وظیفه کاملاً مشخص برخوردار باشد، میتوان گفت که آن کلاس بسیار منجسم است. بنابراین، در کلاس بالا (کلاس Book) اگر اطلاعات مربوط به شخص مانند سن و نام آن حذف شود، Book به یک کلاس با انسجام قوی تبدیل خواهد شد. در کدهای زیر کلاس Book با بیشترین انسجام نشان داده شده است:
class Book{
int price = 299; // ویژگیهای مرتبط با کلاس کتاب
// متدهای مرتبط با کلاس کتاب
public String author(String name) {
return name;
}
public String title(String subject) {
return subject;
}
public int id(int number) {
return number;
}
}
در ادامه مقاله «شی گرایی در جاوا چیست» به بررسی مفهوم انجمنپذیری در جاوا (Association in Java) پرداخته میشود.
انجمنپذیری در شی گرایی جاوا چیست؟
انجمنپذیری در جاوا ارتباطی بین دو کلاس مجزا در برنامه است، این ارتباط با کمک اشیا این کلاسها ایجاد میشود. این روش رابطه بین دو یا چند شی را مشخص میکند. انجمنپذیری در برنامه نویسی میتواند به صورت «یک به یک»، «یک به چند»، «چند به یک»، «چند به چند» صورت پذیرد.
به عنوان مثالی از دنیای واقعی میتوان به رابطه بین یک اتوبوس و مسافران آن اشاره کرد. یک اتوبوس فقط یک راننده دارد یعنی دارای رابطه انجمنپذیری یک به یک است. تعداد زیادی مسافر با یک اتوبوس در ارتباط هستند یعنی دارای انجمنپذیری چند به یک هستند. یک مسافر میتواند با چندین اتوبوس مختلف در ارتباط باشد یعنی انجمنپذیری یک به چند دارد و در نهایت میتوان گفت که چندین مسافر با چندین اتوبوس گوناگون در ارتباط هستند، یعنی انجمنپذیری چند به چند دارند. بدین ترتیب، یک شی با شی دیگری ارتباط برقرار میکند تا از توابع و خدمات ارائه شده توسط شی دیگر استفاده کند. مثال زیر برای درک بهتر انجمنپذیری در جاوا ارائه شده است:
// کلاس اتوبوس
class Bus
{
private String name;
// نام اتوبوس
Bus(String name)
{
this.name = name;
}
public String getBusName()
{
return this.name;
}
}
// کلاس مسافر
class Passenger
{
// نام مسافر
private String name;
// شماره شناسه صندلی مسافر
private int seatId;
Passenger(String name, int seatId)
{
this.name = name;
this.seatId = seatId;
}
public String getPassengerName()
{
return this.name;
}
public int getPassengerId()
{
return this.seatId;
}
}
// انجمنپذیری و ارتباط بین هر دو کلاس در متد اصلی
class Demo
{
public static void main (String[] args)
{
Bus bus = new Bus("Shree Travels");
Passenger psg = new Passenger("Sneha", 52);
System.out.println(psg.getPassengerName() + " with seat number " + psg.getPassengerId()
+ " is a passenger of " + bus.getBusName());
}
}
خروجی کدهای فوق عبارت «Sneha with seat number 52 is a passenger of Shree Travels» است. در این مثال، دو کلاس مجزا «Bus» و «Passenger» به وسیله اشیا خود در داخل کلاس «Demo» با یکدیگر ارتباط انجمنپذیری میگیرند. به این ترتیب، میتوان با استفاده از مفهوم انجمنپذیری، بین دو کلاس مختلف ارتباط برقرار کرد. یک اتوبوس دارای مسافران زیادی است، پس در این مثال ارتباط یک به چند وجود دارد. انجمنپذیری در جاوا دارای دو نوع گوناگون زیر است:
- انجمنپذیری تجمعی (Aggregation)
- انجمنپذیری ترکیبی (Composition)
در ادامه این بخش به توصیف این دو نوع انجمنپذیری مهم و کاربردی پرداخته شده است.
انجمنپذیری تجمعی در شی گرایی جاوا چیست؟
روش تجمعی یا همان «Aggregation»، یک انجمنپذیری ضعیف به حساب میآید. این روش ارتباط بین یک شی با اشیا دیگر را نشان میدهد. Aggregation بخشی از یک رابطه کل را مشخص میکند که در آن یک جزء میتواند بدون یک کل وجود داشته باشد. در ادامه مثالی درباره ارتباط بین گروه «Group» و شخص «Person» مورد بررسی قرار میگیرد. یک شخص میتواند به چندین گروه تعلق داشته باشد. از این رو، یک گروه میتواند دارای چندین شخص باشد. اما اگر کلاس Group حذف شود، برای اشیا کلاس Person مشکلی پیش نمیآید.
این روش رابطه «Has-A» (دارد) را نشان میدهد. Aggregation یک رابطه انجمنپذیر یک طرفه به حساب میآید. برای مثال، یک گروه میتواند اشخاصی را داشته باشد، اما عکس این موضوع ممکن نیست. در Aggregation هر دو ورودی میتوانند به صورت جداگانه زنده بمانند؛ یعنی با پایان دادن به یک موجودیت، برای موجودیتهای دیگر مشکلی پیش نمیآید. بنابراین، هر دو اشیا در Aggregation مستقل هستند. در ادامه مثالی درباره Aggregation ارائه شده است:
import java.util.*;
// کلاس شخص
class Person
{
private String name;
private int age ;
Person(String name, int age)
{
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
/* کلاس گروه شامل یک لیست از اشیا کلاس شخص است.
کلاس گروه با کلاس شخص از طریق اشیا آن مرتبط هستند. */
// کلاس گروه
class Group
{
private String groupName;
private List persons;
Group(String groupName, List persons)
{
this.groupName = groupName;
this.persons = persons;
}
}
// متد اصلی
class Demo
{
public static void main (String[] args)
{
// ایجاد اشیا کلاس شخص
Person a = new Person("Tanmay", 17);
Person b = new Person("Sam", 18);
Person c = new Person("Pitu", 19);
Person d = new Person("Khushi", 20);
// ایجاد فهرستی از اشخاص گروه رفاه اجتماعی
List p1 = new ArrayList();
p1.add(a);
p1.add(c);
// ایجاد فهرستی از اشخاص گروه جشنواره درام
List p2 = new ArrayList();
p2.add(b);
p2.add(d);
// تولید اشیا کلاس گروه
Group swGrp = new Group("Social Welfare", p1);
Group dfGrp = new Group("Drama Fest", p2);
// قبل از حذف گروه جشنواره درام
System.out.println("List of persons in Drama Fest group:");
for(Person p : p2) {
System.out.println("Person name: " + p.getName() + ", Age:" + p.getAge() + ", Group: Drama Fest");
}
// حذف گروه جشنواره درام
dfGrp = null;
// بعد از حذف گروه جشنواره درام
// فهرست اشخاصی که برای آنها مشکلی پیش نمیآید.
System.out.println("List of persons after deleting Drama Fest group:");
for(Person p : p2) {
System.out.println("Person name: " + p.getName() + ", Age: " + p.getAge());
}
}
}
خروجی این برنامه به صورت زیر است (جملههای انگلیسی خروجی برنامه و جملههای فارسی ترجمه آنها جهت درک بهتر مثال هستند):
- (لیست اشخاص در گروه جشنواره درام:) :List of persons in Drama Fest group
- (نام شخص: Sam، سن: ۱۸، گروه: جشنواره درام) Person name: Sam, Age:18, Group: Drama Fest
- (نام شخص: Khushi، سن: ۲۰، گروه: جشنواره درام) Person name: Khushi, Age:20, Group: Drama Fest
- (لیست اشخاص پس از حذف گروه جشنواره درام:) :List of persons after deleting Drama Fest group
- (نام شخص: Sam، سن: ۱۸ ) Person name: Sam, Age: 18
- (نام شخص: Khushi، سن: ۲۰) Person name: Khushi, Age: 20
در این مثال مشاهده شد که دو کلاس Person و Group با کمک اشیا با یکدیگر در ارتباط هستند. دو گروه «جشنواره درام» (Drama Fest) و «رفاه اجتماعی» (Social Welfare) در مثال وجود دارند. این گروهها با استفاده از کلاس Person ساخته شدهاند. گروه فهرستی از اشخاص دارد. همانطور که در خروجی نشان داده شده است دو شخص «Sam» و «Khushi» در گروه جشنواره درام هستند.
سپس، با مساوی قرار دادن نام شی گروه یعنی «dfGrp» با هیچ (null)، گروه جشنواره درام حذف میشود. اما، فهرست اشخاص برنامه به دلیل وجود انجمنپذیری ضعیف خراب نشده و مشکلی برای آنها پیش نیامده است؛ یعنی Aggregation حتی پس از حذف گروه نیز وجود دارد. در ادامه مقاله «شی گرایی در جاوا چیست»، به بررسی انجمنپذیری «Composition» پرداخته شده است.
انجمنپذیری Composition در جاوا چیست؟
«Composition» یک نوع انجمنپذیری قوی به حساب میآید. این روش، بخشی از کل یک رابطه را نشان میدهد. در روش انجمنپذیری Composition، یک بخش بدون یک کل نمیتواند وجود داشته باشد. برای درک بهتر این موضوع مثالی درباره مدرسه و اتاق (کلاس درس مدرسه) ارائه شده است. شی مدرسه شامل تعداد زیادی اتاق میشود. زمانی که شی مدرسه از بین برود، به صورت خودکار تمام اشیای اتاق نیز از بین خواهند رفت. یعنی بدون وجود شی مدرسه، شانسی برای وجود اشیا وابسته آن وجود ندارد.
بنابراین، این مثال نمونه واضحی از یک انجمنپذیری قوی است و این ارتباطات Composition نامیده میشوند. یه طور کلی میتوان گفت که اگر کل کلاس حذف شود، تمام بخشهای آن نیز به دلیل وجود ارتباطات قوی حذف خواهند شد. بنابراین Composition بخشی از رابطه را نشان میدهد. زمانی که بین دو موجودیت انجمنپذیری Composition برقرار شود، شی ایجاد شده بدون شی دیگر نمیتواند وجود داشته باشد. بدین ترتیب، در این روش هر دو موجودیت به یکدیگر وابسته هستند. در ادامه مثالی برای توصیف بیشتر روش انجمنپذیری Composition ارائه شده است.
import java.util.*;
// کلاس اتاق فعالیت
class ActivityRoom {
public String subject;
public int id;
ActivityRoom(String subject, int id)
{
this.subject = subject;
this.id = id;
}
}
// کلاس اداره گروه آموزشی
class Department {
private String name;
// فهرست اتاقهای فعالیت در اداره گروه آموزشی
private List ar;
Department(List ar)
{
this.ar = ar;
}
// دریافت تعداد همه دانشکدهها
public List getActivityRoomsInDepartment()
{
return ar;
}
}
class Demo {
public static void main(String[] args)
{
// ایجاد اشیا کلاس اتاق فعالیت
ActivityRoom a1 = new ActivityRoom("Technical", 601);
ActivityRoom a2 = new ActivityRoom("Business", 602);
ActivityRoom a3 = new ActivityRoom("Economics", 603);
// ساخت فهرستی از اتاقهای فعالیت
List act = new ArrayList();
act.add(a1);
act.add(a2);
act.add(a3);
// ایجاد شی کلاس اداره گروه آموزشی
Department d = new Department(act);
// ساخت فهرستی از اتاقهای فعالیت در اداره گروه آموزشی
List arlist = d.getActivityRoomsInDepartment();
for (ActivityRoom a : arlist) {
System.out.println(a.subject + " activity room with id " + a.id);
}
}
}
خروجی برنامه فوق به صورت زیر است(جملههای انگلیسی خروجی برنامه و جملههای فارسی ترجمه آنها جهت درک بهتر مثال به حساب میآیند.):
- Technical activity room with id 601 (اتاق فعالیتهای فنی با شناسه ۶۰۱)
- Business activity room with id 602 (اتاق فعالیتهای کسب و کار با شناسه ۶۰۲ )
- Economics activity room with id 603 (اتاق فعالیتهای اقتصادی با شناسه ۶۰۳)
در این مثال دو کلاس اتاق فعالیت (ActivityRoom) و اداره گروه آموزشی (Department) وجود دارند. اداره گروه آموزشی از چندین اتاق فعالیت تشکیل شده است. بنابراین، اگر برای Department مشکلی پیش بیاید و این کلاس از بین برود، همه ActivityRoomهای داخل کلاس Department نیز از بین خواهند رفت و این موضوع به وضوح مفهوم انجمنپذیری composition را نشان میدهد. پس از بررسی جامع مبحث انجمنپذیری در جاوا، بخش بعدی مقاله «شی گرایی در جاوا چیست» به شرح متدها در این زبان شی گرا اختصاص داده شده است.
متدها در جاوا
متدها در زبان جاوا، بلوکهایی از کدها یا مجموعهای از عبارتهایی هستند که با یکدیگر در یک گروه قرار گرفتهاند و برای تکمیل یک وظیفه معین یا یک عملکرد مورد استفاده قرار میگیرند. متدها جهت به دست آوردن قابلیت استفاده مجدد از کدها اهمیت بالایی دارند. متد میتواند یک بار نوشته شود و چندین بار در برنامه مورد استفاده قرار بگیرد.
همچنین متدها امکان ویرایش و خوانایی کدها را نیز فراهم میکنند. متدها فقط زمانی استفاده میشوند که در برنامه فراخونی شده یا به آنها استناد شود. در زبان برنامه نویسی شی گرا جاوا متدها به دو روش زیر تعریف میشوند:
- متدهای از پیش تعریف شده (Pre-Defined Method)
- متدهایی که توسط کاربر تعریف شدهاند. (User-Defined Method)
متدهای از پیش تعریف شده، آنهایی هستند که قبلاً توسط کتابخانههای کلاس جاوا تعریف شدهاند. زمانی که یک متد خاص توسط کاربر یا برنامه نویس نوشته شود، به عنوان نوعی از متدها در نظر گرفته میشود که توسط کاربر تعریف شده است. متدهایی که توسط کاربر تعریف شدهاند، بر حسب نیاز میتوانند در حین نوشتن برنامه تغییر پیدا کنند. به صورت کلی متدها در جاوا به چهار نوع زیر تقسیم شدهاند:
- متد استاتیک (Static method)
- متد انتزاعی (Abstract method)
- متد نهایی کننده (Finalize method)
- متد برابری (Equals method)
در ادامه این بخش به بررسی هر یک از انواع متدهای فوق پرداخته شده است. در ابتدا متد استاتیک در جاوا مورد بحث قرار میگیرد.
متد استاتیک در جاوا چیست؟
متدهای استاتیک در برنامههای جاوا، متدهایی هستند که زمان اعلان آنها از کلمه کلیدی «static» استفاده میشود. به عبارت دیگر، متدی که به یک کلاس تعلق دارد اما نمونهای (Instance) از آن کلاس نیست، به عنوان یک متد استاتیک شناخته میشود. میتوان متدها را با استفاده از نوشتن کلمه کلیدی static قبل از نام متد تعریف کرد. مزیت اصلی متد استاتیک این است که میتوان این متد را بدون تعریف کردن حتی یک شی، ایجاد کرد.
متد استاتیک میتواند به اعضای داده استاتیک (Static Data Member) دسترسی داشته باشد و همچنین مقادیر آنها را تغییر دهد. این روش برای ایجاد متد نمونه (Instance Method) استفاده و به وسیله نام کلاس فراخوانی میشود. در کدهای زیر متد «()main» یک مثال ساده از روش ایجاد متدهای استاتیک است.
public class Demo
{
public static void main(String[] args)
{
displaymethod();
}
static void displaymethod()
{
System.out.println("It is an example of static method.");
}
}
خروجی این متد به صورت عبارت «It is an example of a static method» به معنی «این یک مثال از متد استاتیک است.» چاپ میشود. در ادامه این بخش به بررسی متد انتزاعی در جاوا پرداخته میشود.
متد انتزاعی در جاوا چیست؟
متدهای انتزاعی در کدهای جاوا، زمان اعلانشان از کلمه کلیدی «abstract» استفاده میکنند. متدهای انتزاعی پیادهسازی، بدنه یا بلوک برای کدهایشان ندارند. متدهای انتزاعی همیشه باید در کلاسهای انتزاعی تعریف شوند، یا میتوان گفت اگر کلاسی دارای متدهای انتزاعی است باید به صورت انتزاعی اعلان شود.
اما برعکس این موضوع درست نیست، یعنی کلاس انتزاعی نیازی به داشتن متد انتزاعی اجباری ندارد. همچنین، اگر کلاس معمولی یک کلاس انتزاعی را گسترش دهد، کلاس باید همه متدهای انتزاعی کلاس والد انتزاعی را پیادهسازی کند یا کلاس به صورت انتزاعی اعلان شود. در ادامه مثالی جهت درک بهتر مفهوم این متدها مشاهده میشود.
// کلاس انتزاعی مساحت
abstract class Area{
/* .اینجا دو متد انتزاعی وجود دارد، کلاس فرزند باید این متدها را پیادهسازی کند */
public abstract int areaSquare(int s);
public abstract int areaRectangle(int l, int b);
// متد نرمال
public void display(){
System.out.println("Normal method in abstract class Area");
}
}
// .کلاس معمولی، کلاس انتزاعی را گسترش میدهد
class Demo extends Area{
/* .اگر پیادهسازی این دو متد انجام نگیرد، برنامه خطای کامپایل دریافت میکند */
public int areaSquare(int s){
return s*s;
}
public int areaRectangle(int l, int b){
return l*b;
}
public static void main(String args[]){
Area a = new Demo();
System.out.println("Area of square " + a.areaSquare(9));
System.out.println("Area of rectangle " + a.areaRectangle(3,4));
a.display();
}
}
عبارتهای زیر خروجی این برنامه هستند. (جملههای انگلیسی خروجی برنامه و جملههای فارسی ترجمه آنهاست.)
(مساحت مربع ۸۱ است.) Area of square 81
(مساحت مستطیل ۱۲ است.) Area of rectangle 12
(متد نرمال در کلاس انتزاعی مساحت یا Area) Normal method in abstract class Area
بخش بعدی به بررسی متدهای نهایی کننده در جاوا اختصاص داده شده است.
متد نهایی کننده در جاوا چیست؟
متدهای نهایی کننده در جاوا با استفاده از کلمه کلیدی «final» فراخوانی میشوند. این متدها دارای قابلیت «override» نیستند. این مسئله به این معنی است که کلاس فرزند میتواند متد نهایی کننده کلاس والد را بدون مشکل فراخوانی کند، اما نمیتواند آن را override کند.
زیرا هدف اصلی ساخت متد نهایی کننده متوقف کردن ویرایش متد به وسیله زیر کلاسهاست. مثال متد نهایی کننده در ادامه مشاهده میشود.
class DemoParent{
final void method(){
System.out.println("Parent class final method");
}
}
class Demo extends DemoParent{
// خطا
void method(){
System.out.println("final method modified inside child class");
}
public static void main(String args[]){
Demo d = new Demo();
d.method();
}
}
در کدهای فوق به دلیل اینکه قصد تغییر متد نهایی کننده در کلاس فرزندِ (Demo) کلاس والد (DemoParent) وجود داشته است، به بروز خطا منجر میشود. جهت جلوگیری از ایجاد خطا، به جای تغییر متد در کلاس فرزند، میتوان از کدهای زیر استفاده کرد:
class DemoParent{
final void method(){
System.out.println("Parent class final method");
}
}
class Demo extends DemoParent{
public static void main(String args[]){
Demo d = new Demo();
d.method();
}
}
خروجی این کد عبارت «Parent class final method» به معنی «متد نهایی کننده کلاس والد» است. در ادامه این بخش از مقاله به بررسی متد برابری در زبان جاوا پرداخته میشود.
متد برابری در جاوا چیست؟
این متد همانطور که از نامش یعنی «()equals.» پیداست، جهت مقایسه برابری دو شی مورد استفاده قرار میگیرد. متد ()equals. در زبان جاوا جهت بررسی مقادیر مساوی دو رشته (String) استفاده میشود و آنها را کاراکتر به کاراکتر مورد بررسی قرار میدهد. متد برابری در جاوا نباید با عملگر «==» اشتباه گرفته شود.
این متد دو رشته را بر حسب محتوای آنها مقایسه میکند، در حالی که عملگر «==» برای مقایسه آدرسها استفاده میشود. اگر محتوای رشتهها کاملاً مثل هم باشند، متد برابری کلمه «true» را برمیگرداند، در غیر این صورت «false» نشان داده خواهد شد. در کدهای زیر مثالی جهت تفهیم متد برابری ارائه شده است.
public class Demo {
public static void main(String[] args)
{
String s1 = "GreatLearning";
String s2 = "GreatLearning";
String s3 = new String("GreatLearning");
System.out.println(s1 == s2); // true
System.out.println(s1 == s3); // false
System.out.println(s1.equals(s2)); // true
System.out.println(s1.equals(s3)); // true
}
}
با اینکه شی «s1» و «s3» با یک نوع محتوا ایجاد شدهاند، به عنوان دو نوع گوناگون در حافظه ذخیره میشوند. از این رو، در زمان برابر قرار دادن این دو شی با عملگر «==» جواب غلط دریافت میشود و در زمان برابر قرار دادن آنها توسط متد برابری جواب درستی نشان داده شده است. در بخش بعدی مقاله «شی گرایی در جاوا چیست» به بررسی روش فرستادن پیام (Message Passing) در این زبان پرداخته میشود.
فرستادن پیام در جاوا
ارسال پیام در کامپیوترها، یک پدیده ارتباطی مابین پردازشها است. این پدیده یک نوع ارتباط برای شی گرایی در جاوا به حساب میآید. این عمل در جاوا مانند فرستادن شی است یعنی میتوان گفت که به ارسال پیام از یک «Thread» (نخ) به «Thread» دیگر، فرستادن پیام گفته میشود. Threadها کلاسهایی هستند که وظایف آنها به صورت موازی با یکدیگر انجام میگیرند. روش فرستادن پیام هنگامی استفاده میشود که threadها حافظه مشترک ندارند و قادر به اشتراکگذاری پایشگرها (Monitor) یا هر متغیر مشترک دیگری برای برقراری ارتباط نیستند.
در این رویکرد، برنامه پیامی را به فرآیند ارسال میکند و برنامه جهت اجرای عملکردش به فرآیند وابسته است. پیادهسازی فرستادن پیام دشوار نیست، کارایی سریعتری دارد و میتوان مدلهای موازی بزرگ به وسیله آن ایجاد کرد. این روش دارای دو نوع زیر است:
- ارسال پیام همزمان (Synchronous Message Passing): زمانی که اشیا در یک زمان پیادهسازی شوند، ارسال پیام همزمان یا همان سنکرون اتفاق میافتد.
- ارسال پیام غیر همزمان (Asynchronous Message Passing): در روش غیر همزمان یا آسنکرون، هنگامی که شی درخواست کننده (Requesting Object) پیامی را ارسال میکند، شی دریافت کننده ( Receiving Object) میتواند قطع (Down) یا مشغول باشد.
در بخش بعدی به بررسی اینکه آیا سه مفهوم اصلی شی گرایی در جاوا یعنی پلی مورفیسم، کپسوله سازی و وراثت میتوانند با هم کار کنند و ترکیب شوند یا خیر پرداخته شده است.
آیا پلی مورفیسم، کپسوله سازی و وراثت در شی گرایی در جاوا میتوانند با هم کار کنند؟
زمانی که سه عمل پلی مورفیسم، کپسوله سازی و وراثت جهت تولید محیط برنامه نویسی شی گرا در جاوا با یکدیگر ترکیب میشوند، این محیط از توسعه برنامههای بسیار قوی و مقیاسپذیرتر جهت انجام برنامه نویسی شی گرا پشتیبانی میکند. یک مدل با طراحی خوب یا با کلاسهای سلسله مراتبی، دلیلی جهت استفاده مجدد از کدهایی است که برنامه نویس زمان و تلاش خود را صرف توسعه و تست آن میکند. کپسوله سازی در جاوا امکان انتقال پیادهسازیهایی را در طول زمان اجرا بدون شکستن (تقسیم) کدهای وابسته به واسطهای عمومی کلاسها، ایجاد میکند. با استفاده از پلی مورفیسم در جاوا کدهایی با قابلیت خوانایی بالا، تمیز و معقول تولید میشوند.
در شی گرایی در جاوا جهت استفاده از کپسوله سازی، پلی مورفیسم و وراثت، هر کدام از اجزا به یک شی تبدیل میشوند؛ برای مثال میتوانند موبایل، اتومبیل، تلفن و سایر موارد باشند. این موضوع درباره برنامههای کامپیوتری نیز صدق میکند. به وسیله اصول برنامه نویسی شی گرا در جاوا، بخشهای مختلف برنامههای پیچیده در کنار یکدیگر قرار میگیرند تا یک برنامه منسجم، قوی و قابل نگهداری تشکیل شود. بسیاری از ویژگیهایی که در زبان جاوا وجود دارند، بخشی از کتابخانههای کلاسهای ساخته شده در جاوا هستند که به صورت گسترده در کپسوله سازی، پلی مورفیسم و وراثت مورد استفاده قرار میگیرند.
در این بخش یک مثال از دنیای واقعی در نظر گرفته و ارائه میشود. میتوان به انسانها به عنوان مسئله وراثت نگاه کرد و اتومبیلها مانند برنامههایی فرض میشوند که توسط برنامه نویس نوشته شدهاند. همه رانندهها برای راندن انواع مختلف وسایل نقلیه به یک وراثت وابسته هستند. به دلیل این که انواع گوناگونی از اتومبیلها وجود دارند، مردم واسط بین ویژگی اتوبیلها و تفاوتهای میان آنها هستند. پیادهسازی قسمتهایی از وسایل نقلیه مانند موتورها، ترمزها و سایر موارد؛ ابتدا تحت عملیات کپسوله سازی انجام میگیرد و سپس روی آن پلی مورفیسم انجام میشود.
با استفاده از این روش، ناحیه وسیعی از گزینهها برای یک نوع وسیله نقلیه مانند سیستم ترمز ضد قفل، سیستم ترمز سنتی یا سیستم ترمز قدرتی ایجاد خواهد شد. به یک وسیله نقلیه که دارای انواع گوناگون ترمز است، پلی مورفیسم گفته میشود. این مثال ترکیبی از کپسوله سازی، وراثت و پلی مورفیسم را در جاوا نشان داد. در ادامه مقاله «شی گرایی در جاوا چیست» انواع مزایای استفاده از مفهوم شی گرایی مورد بررسی قرار میگیرند.
مزایای مفهوم شی گرایی در جاوا
مفهوم برنامه نویسی شی گرا یکی از رویکردهای اصلی توسعه به حساب میآید که به طور گسترده در تعداد زیادی از زبانهای برنامه نویسی امروزی پذیرفته شده است.
در این بخش به برخی از مزایای شی گرایی در جاوا پرداخته شده است که در ادامه بررسی میشوند. اولین مزیت ارائه شده به تعریف رویکرد قابلیت استفاده مجدد (Re-usability) در شی گرایی اختصاص داده شده است.
قابلیت استفاده مجدد در شی گرایی
زمانی که از قابلیت استفاده مجدد از کدها صحبت میشود یعنی نوشتن کدها یک بار انجام میگیرد و چندین بار از آنها استفاده میشود. در این رویکرد امکانات قبلی مجدداً مورد استفاده قرار میگیرند و نیازی به نوشتن دوباره کدها نیست. با استفاده از کلاسها میتوان به این امکانات دسترسی پیدا کرد. هر زمانی که نیاز باشد چندین بار میتوان از امکانات مورد نظر بهرهمند شد. در ادامه این بخش به بررسی مزیت افزونگی داده (Data Redundancy) در شی گرایی پرداخته میشود.
افزونگی داده در شی گرایی
این رویکرد یکی از مهمترین و بهترین مزیتهای برنامه نویسی شی گرا به حساب میآید. افزونگی داده در شی گرایی به حالتی گفته میشود که در محل ذخیرهسازی دادهها یک قطعه یکسان از دادهها در دو مکان متفاوت نگهداری شده باشد. اگر از یک عملکرد یکسان در چندین کلاس استفاده شود، میتوان عملکرد این کلاسها را جهت ز وظایف یکسان به وسیله ارث بری تعریف کرد. در این صورت از ذخیره دادههای یکسان در مکانهای گوناگون جلوگیری میشود. در بخش بعدی به بررسی مزیت قابلیت نگهداری کدها (Code Maintenance) پرداخته شده است.
قابلیت نگهداری کدها در شی گرایی
به وسیله این قابلیت، تغییر و نگهداری کدهای موجود به عنوان اشیا جدید آسان است. این کدها میتوانند به وسیله تغییرات کوچک در برنامههای موجود مورد استفاده قرار بگیرند. همچنین این قابلیت به کاربران کمک میکند تا بارها کار مجدد انجام دهند. قابلیت نگهداری کدها باعث صرفهجویی در زمان میشود چون با ایجاد تغییرات جدید در کدهای قبلی از آنها مجدداً استفاده میشود. در ادامه بخش مزیتهای برنامه نویسی شی گرا، در بخش بعدی به مبحث امنیت (Security) شی گرایی در جاوا پرداخته شده است.
امنیت در شی گرایی
پنهان کردن دادهها و انتزاع در شی گرایی برای فیلتر کردن دادههایی انجام میگیرند که مورد نیاز نیستند. این موضوع به این معنی است که فقط از دادههای مورد نیاز جهت حفظ امنیت برنامه در کدها استفاده میشود. در بخش بعدی این مقاله مزایای طراحی (Design Benefit) شی گرایی در جاوا بررسی شدهاند.
مزایای طراحی در شی گرایی
اگر طراحان بخواهند که نتیجه خوبی به دست بیاورند، فاز طولانی و گستردهای را در پیش دارند. در زمانی که برنامه به موقعیتهای بحرانی برسد، طراحی کدهای برنامه غیر شی گرا به صورت جداگانه آسانتر است. پس بهتر است برنامهها به صورت شی گرا طراحی و نوشته شوند تا به صورت منسجمتر و غیر جداگانه باشند. در ادامه این بخش، رویکرد عیبیابی آسان (Easy Troubleshooting) معرفی شده است.
عیبیابی آسان در شی گرایی
اشیایی که کپسوله سازی میشوند، فقط به خودشان محدود هستند یعنی تغییراتشان روی دیگر اشیا و کلاسها تأثیری ندارد. بنابراین، اگر توسعه دهندگان با مشکلی مواجه شوند، به راحتی قابل حل است و هیچ احتمالی مبنی بر دوگانگی حین بر طرف کردن مشکل کدها وجود ندارد. در ادامه این بخش، تعریفی از مزیت انعطافپذیری (Flexibility) شی گرایی در جاوا ارائه شده است.
انعطافپذیری در شی گرایی
استفاده از روشهای طراحی کد به وسیله شی گرایی در جاوا، انعطافپذیری در نوشتن کدها را با روشهای گوناگون شی گرایی افزایش میدهد. به عنوان مزیت آخر شی گرایی در جاوا، در بخش بعدی به تعریفی از مزیت حل مسئله (Problem solving) پرداخته شده است.
حل مسئله در شی گرایی
به دلیل وجود انواع رویکردهای گوناگون در شی گرایی و تنوع در ایجاد و تولید اشیا و کلاسها، مسائل میتوانند به وسیله انواع روشهای مختلف پیادهسازی و حل شوند. در بخش بعدی مقاله «شی گرایی در جاوا»، به معایب محدود شی گرایی در جاوا پرداخته شده است.
معایب مفهوم شی گرایی در جاوا
همانطور که در بخشهای پیشین گفته شد شی گرایی مزایای بسیاری دارد. اما علاوه بر آنها دارای معایب محدودی نیز است که در مقابل مزایای آن قابل چشمپوشی هستند.
در ادامه این معایب معرفی میشوند:
- تکاپو (Effort): وظایف زیادی در برنامههای شی گرا، گنجانده شدهاند.
- سرعت (Speed): سرعت برنامههای شی گرا نسبت به دیگر برنامهها کندتر است.
- اندازه (Size): برنامههای شی گرا، دارای اندازههای بزرگتری نسبت به دیگر برنامهها هستند.
در بخش بعدی این مطلب، به بررسی تفاوت بین برنامه نویسی شی گرا، برنامه نویسی رویهای (Procedural Oriented Programming) و برنامه نویسی ساختار یافته (Structured Programming) پرداخته شده است.
تفاوت بین برنامه نویسی شی گرا، رویهای و ساختار یافته
در این بخش به بررسی چند تفاوت بین برنامه نویسی شی گرا، برنامه نویسی رویهای و برنامه نویسی ساختار یافته به صورت خلاصه پرداخته میشود.
- برنامه نویسی شی گرا، شی محور است و عناصر آن از اشیا تشکیل میشوند. اما برنامه نویسی رویهای، یک نوع برنامه نویسی ساختار یافته است.
- روشهای کدنویسی به وسیله رویکردهای شی گرا از یک رویکرد پایین به بالا (Bottom Up Approach) تعبیت میکنند. اما برنامههای رویهای به بخشهای کوچکی به نام تابع تقسیم میشوند.
- در برنامه نویسی شی گرا، کدها به بخشهای کوچکی به نام اشیا تقسیم شدهاند. اما برنامه نویسی رویهای از یک رویکرد بالا به پایین (Top Down Approach) استفاده میکند.
- برنامههای شی گرا دارای مشخص کنندههای (Specifiers) دسترسی عمومی، خصوصی، محافظت شده و سایر موارد هستند. ولی برنامههای رویهای هیچ مشخص کنندهای برای دسترسیهایشان ندارند.
- اضافه کردن تابع یا داده جدید در برنامههای شی گرا آسان است ولی در برنامههای رویهای این چنین نیستند.
- برنامه نویسی شی گرا میتواند دادههای پنهان شده فراهم کند و امنیت بالایی دارد. اما برنامه نویسی رویهای این قابلیت را ندارد و امنیت آن پایین است.
- ایجاد اضافه بار در برنامه نویسی شی گرا امکانپذیر است. ولی در برنامه نویسی رویهای این رویکرد وجود ندارد.
- به عنوان مثالهایی از برنامه نویسی شی گرا میتوان زبان «++C»، جاوا، پایتون و سایر موارد را نام برد. زبانهای قدیمیتری مانند فرترن (FORTRAN)، کوبل (Cobol) و سایر موارد، از رویکرد برنامه نویسی رویهای استفاده میکنند.
- برنامه نویسی ساختار یافته برنامهها را به دو قسمت توابع و ماژولها تقسیم میکنند. استفاده از توابع و ماژولها قابلیت فهمیدن و خوانایی برنامه را افزایش میدهد. در این نوع برنامه نویسی توابع بیشتر از دادهها اهمیت دارند. تمرکز این زبان روی توسعه اپلیکیشنهای نرم افزاری بزرگ است. زبان برنامه نویسی «C» و پاسکال (pascal) نمونههایی از زبانهای برنامه نویسی ساختار یافته هستند.
به این ترتیب، در این مقاله سعی شد تا حد امکان به طور جامع به این سوال پاسخ داده شود که شی گرایی در جاوا چیست و به مباحث پیرامون آن از جمله مفاهیم، ویژگیها، مزایا و معایب شی گرایی در جاوا نیز پرداخته شد.
جمعبندی
با پیشرفت روز افزون انواع زبانهای برنامه نویسی، مشخص است که یادگیری زبانهای جدید شی گرا مانند جاوا کمک بسزایی در مسیر شغلی و علمی افراد و پیشرفت تکنولوژی خواهد داشت. به همین دلیل، یادگیری شی گرایی در جاوا به عنوان یک رویکرد مهم در این مقاله مورد بررسی قرار گرفت.
در مقاله «شی گرایی در جاوا چیست»، به طور خلاصه به موارد زیر پرداخته شد:
- برنامه نویسی شی گرا برای طراحی برنامه به وسیله کلاسها و اشیا استفاده میشود.
- شی گرایی در جاوا، هسته اصلی زبان جاوا در نظر گرفته میشود.
- اشیا نمونههای کلاسها و همچنین موجودیتهای دنیای واقعی هستند.
- کلاسها مجموعههایی از اشیا هستند؛ کلمه کلیدی «class» جایی نوشته میشود که قرار است کلاسی نوشته یا نامگذاری شود.
- پلی مورفیسم در شی گرایی به معنی عملکردهای گوناگون برای یک وظیفه است که با استفاده از آنها رویکرد رونویسی و بار اضافه انجام میگیرد.
- انتزاع در شی گرایی به پنهان کردن دادهها اشاره میکند، این رویکرد فقط اطلاعاتی را نمایش میدهد که کاربر نیاز دارد.
- وراثت در شی گرایی فرآیند به دست آوردن یا به ارث بردن ویژگیهای کلاسها از یکدیگر به حساب میآید.
- کپسوله سازی در شی گرایی به معنی بستهبندی کردن اطلاعات است و از متدهای «get» و «set» برای دستیابی به دادههای کپسوله شده استفاده میشود.
- مفاهیم برنامه نویسی شی گرا دارای قابلیتهای استفاده مجدد از کدها، نگهداری کدها، افزونگی داده، امنیت بالا و سایر موارد میشود.
به این ترتیب، سعی شد در مقاله «شی گرایی در جاوا چیست» به طور جامع و کامل به بررسی این موضوع پرداخته شود.