مفاهیم برنامهنویسی شیگرایی
برنامهنویسی شیگرایی (OOP) سرنام Object-oriented programming به نوع خاصی برنامهنویسی کامپیوتری اشاره دارد که در آن برنامهنویس نوع دادهای یک ساختار داده و انواع عملیاتی (توابع) که امکان اجرای آنها روی ساختار داده فراهم است را تعریف میکند. به این ترتیب، ساختار داده به شیای تبدیل میشود که شامل دادهها و توابع است. علاوه بر این، برنامهنویسان میتوانند روابط بین یک شی با شی دیگر را ایجاد کنند. بهطور مثال، اشیا میتوانند خصوصیاتی را از اشیا دیگر به ارث ببرند. یکی از مزایای اصلی پارادایم برنامهنویسی شیگرا نسبت به تکنیکهای برنامهنویسی رویهای این است که به توسعهدهندگان اجازه میدهند بدون نیاز به تغییر ماژولها در زمان تعریف اشیا جدید از ماژولها استفاده کنند. یک برنامهنویس میتواند به سادگی یک شی جدید ایجاد کند و بیشتر ویژگیهای شی موجود را به ارث ببرد. اینکار باعث سهولت در برنامهنویسی شیگرایی میشود.
بیشتر زبانهای برنامهنویسی مدرن از پارادایم شیگرایی پشتیبانی میکنند، با این حال برخی از زبانهای برنامهنویسی قدیمی مانند پاسکال نیز یک چنین قابلیتی را ارائه میکنند. از زبانهای برنامهنویسی شیگرا سطح بالا میتوان به جاوا، سی پلاسپلاس، سی شارپ، پایتون، اسمالتاک و غیره اشاره کرد. پارادایم برنامهنویسی شیگرا با مفاهیم مهمی به شرح زیر احاطه شدهاند:
انتزاع (Abstraction)
انتزاع به فرآیند چیدن ویژگیهای مشترک اشیا و رویهها اشاره دارد. این مفهوم دادهها را از یک استخر بزرگ انتخاب میکند تا فقط جزئیات مربوط به آن شی را به کاربر نشان دهد. انتزاع فقط ویژگیهای اساسی را "نشان میدهد" و اطلاعات غیرضروری را "پنهان" میکند. انتزاع به کاهش پیچیدگی و بهبود عملکرد برنامهنویس کمک میکند. به همین دلیل یکی از مهمترین مفاهیم برنامهنویسی شیگرایی است. پنهان کردن اطلاعات به معنای پنهان کردن جزئیات یک شی یا تابع است. پنهان کردن اطلاعات یک روش برنامهنویسی قدرتمند است، زیرا پیچیدگیها را کم میکند.
کپسولهسازی (Encapsulation)
کپسولهسازی فرآیند ترکیب عناصر برای ساخت یک موجودیت جدید است. روال یا رویه نوعی فرآیند کپسولهسازی است، زیرا مجموعهای از دستورالعملهای کامپیوتری را با هم ترکیب میکند. کپسولهسازی یکی از مفاهیم اساسی برنامهنویسی شیگرا (OOP) است. کپسولهسازی دادهها و متدهایی را توصیف میکند که در قالب یک مفهوم واحد همچون یک کلاس کار میکنند. این مفهوم همچنین برای پنهان کردن نمای داخلی یا حالت یک شی از جهان خارج نیز استفاده میشود. به بیان دقیقتر، تنها اطلاعات موردنیاز به جهان خارج نشان داده میشود. ایده کلی این مکانیسم ساده است. اگر خصلتی دارید که برای جهان خارج شی نمایان نیست و این امکان فراهم است تا با متدهایی که امکان خواندن یا نوشتن به شی را فراهم میکنند این خصلت را در اختیار جهان خارج قرار دهید، شما میتوانید اطلاعات خاص را پنهان کنید و وضعیت داخلی یک شی را کنترل کنید.
وراثت (Inheritance)
وراثت مکانیزمی است که در آن یک طبقه مالکیت را به دست میآورد یا به عبارت دقیقتر از طبقه دیگری ارثبری میکند. بهطور مثال، كودك صفات والدین خود را به ارث میبرد. با استفاده از وراثت، میتوانیم از فیلدها و متدهای درون یک کلاس دومرتبه استفاده کنیم. از اینرو، وراثت قابلیت استفاده مجدد را تسهیل میکند و برنامهنویسی شیگرایی را کاربردیتر میکند.
انواع وراثت
وراثت منفرد (Single inheritance)
وراثت منفرد به یک کلاس مشتق شده اجازه میدهد خصوصیات و رفتار را از یک کلاس والد به ارث ببرد. به بیان سادهتر وراثت منفرد اجازه میدهد تا یک کلاس مشتق شده خصوصیات و رفتار یک کلاس پایه را به ارث ببرد، بنابراین امکان استفاده مجدد از کد و افزودن ویژگیهای جدید به کد موجود را فراهم میکند. اینکار باعث میشود تا کدهای دقیقتری داشته باشیم و مجبور نشویم کدهای تکراری بنویسیم. در وراثت منفرد یک کلاس دیگری را گسترش میدهد (فقط یک کلاس).
در شکل بالا کلاس B ویژگیها را فقط از کلاس A به ارث میبرد. کلاس A یک ابر کلاس و کلاس B یک زیر کلاس است.
وراثت چندگانه (Multiple Inheritance)
وراثت چندگانه یکی از ویژگیهای مربوط به زبانهای برنامهنویسی شیگرا است که در آن یک شی یا کلاس میتواند ویژگیها و خصلتهای یک یا چند شی والد را به ارث ببرد.
در شکل بالا، کلاس C ویژگیهای کلاس A و کلاس B را به ارث میبرد.
وراثت چند سطحی (Multilevel Inheritance)
در وراثت چند سطحی یک کلاس میتواند از یک کلاس مشتق شده ارثبری کند. از این رو، کلاس مشتق شده به کلاس پایه برای کلاس جدید تبدیل میشود.
همانگونه که در شکل بالا مشاهده میکنید، کلاس C زیر کلاس B و B زیرکلاس A است.
وراثت سلسلهمراتبی (Hierarchical Inheritance)
زمانیکه بیش از یک کلاس از کلاسی یکسان ارثبری کنند، این مفهوم وراثت سلسلهمراتبی نام دارد. به عبارت دیگر، زیر کلاسهای متعددی از یک کلاس ارثبری میکنند. در وراثت سلسلهمراتبی یک کلاس والد میتواند فرزندان زیادی داشته باشد.
همانگونه که در شکل بالا مشاهده میکنید کلاس B، C و D همگی از کلاس A ارثبری میکنند.
وراثت ترکیبی (Hybrid Inheritance)
وراثت ترکیبی نوع دیگری از وراثت است. یک کلاس ترکیبی از دو یا چند کلاس در قالب سلسله مراتبی ارثبری میکند و در این حالت کلاسها میتوانند از کلاس والد یکسانی در قالب وراثت سلسله مراتبی ارثبری کنند.
در ارثبری ترکیبی آنگونه که در شکل بالا مشاهده میکنید، تمامی عضوهای عمومی و محافظت شده کلاس A توسط کلاس D ارثبری از طریق کلاس B و سپس از کلاس C ارثبری شدهاند.
تعیین سطح دسترسی
تعیینکنندههای سطوح دسترسی چگونگی دسترسی به عضوهای یک کلاس را مشخص میکنند. بهطور معمول، سه تعیین کننده عمومی (Public)، خصوصی (Private) و محافظت شده (Protected) وجود دارد.
عمومی (Public)
عضوهای یک کلاس که به صورت عمومی معرفی میشوند در خارج از کلاس نیز در دسترس قرار دارند و امکان استفاده از آنها وجود دارد.
خصوصی (Private)
عضوهای یک کلاس که به صورت خصوصی تعریف میشوند درون آن کلاس در دسترس قرار دارند، اما دسترسی به آنها خارج از کلاس فراهم نیست. بهطور پیشفرض متغیرها و توابع عضو به صورت خصوصی تعریف میشوند.
محافظت شده (Protected)
عضوهای یک کلاس که به صورت محافظت شده تعریف میشوند رویکردی شبیه به تعیینکنندهای دسترسی خصوصی دارند. این متغیرها از خارج از کلاس غیر قابل دسترس هستند، اما در زیرکلاسها امکان دسترسی به آنها وجود دارد.
چندریختی (Polymorphism)
چند ریختی به توانایی یک شی به دریافت انواع مختلفی از شکلها اشاره دارد. متداولترین کاربرد چند ریختی در برنامهنویسی شیگرا زمانی اتفاق میافتد که از مرجع کلاس والد برای ارجاع به شی کلاس فرزند استفاده میشود. چندریختی میتواند ایستا یا پویا باشد. در چندشکلی ایستا، پاسخ به یک تابع در زمان کامپایل تعیین میشود. در چندشکلی پویا پاسخ به یک تابع در زمان اجرا تعیین میشود. بنابراین، چند ریختی به دو صورت زیر در دسترس است:
1. چندشکلی زمان کامپایل (ایستا)
2. چند شکلی زمان اجرا (پویا)
چند شکلی زمان کامپایل
پیوند دادن یک تابع به یک شی در طول زمان کامپایل اتصال زودهنگام (early binding) نامیده میشود. این حالت بهنام مقیدسازی ایستا (static binding) نیز شناخته میشود. دو روش برای پیادهسازی چندشکلی ایستا وجود دارد.
1. سربارگذاری تابع (Function overloading)
2. سربارگذاری عملگر (Operator overloading)
سربارگذاری تابع
سربارگذاری تابع یک ویژگی است که در آن دو یا چند تابع میتوانند نام یکسان، اما پارامترهای مختلفی داشته دارند. دو یا چند تابع با نام یکسان، اما آرگومانهای متفاوت بهنام سربارگذاری تابع شناخته میشوند. مثال زیر نمونهای از سربارگذاری تابعی بهنام test را نشان میدهد.
int test() { }
int test(int a) { }
float test(double a) { } int test(int a, double b) { }
در مثال بالا، تمامی 4 تابع از رویکرد سربارگذاری تابع استفاده کردهاند، زیرا آرگومانهای اختصاص داده شده به توابع متفاوت است.
سربارگذاری عملگر
یک عملگر در یک زبان برنامهنویسی سبملی است که به کامپایلر یا مفسر اعلام میکند تا یک عمل ریاضی، منطقی یا رابطهای خاص را انجام دهند تا یک نتیجه مشخص از انجام آن عمل دریافت شود. بهطور مثال، +، -، * و ÷ عملگرهای ریاضی و سمبلهایی همچون &، | و ! عملگرهای منطقی و سمبلهایی همچون >، <، = و غیره عملگرهای رابطهای هستند. سربارگذرای عملگر نوعی چندشکلی است که در کاربر کاربردهای مختلفی برای عملگر تعریف کرده است. سربارگذاری عملگر بیشتر زمانی استافده میشود که کاربر قصد دارید روی نوعهای دادهای خودتعریفی یکسری محاسبات انجام دهد. بهطور مثال، عملگر "+" برای پیادهسازی عملیات جمع روی نوعهای دادهای مختلف همچون صحیح (Integer) یا رشتهای (String) استفاده میشود.
چند شکلی زمان اجرا
چند شکلی زمان اجرا یا توزیع متد پویا (Dynamic Method Dispatch) یا اتصال با تاخیر فرآیندی است که در آن فراخوانی یک تابع رونویسی شده (overridden) به جای زمان کامپایل در زمان اجرا انجام میشود. در این فرآیند یک متد رونویسی شده از طریق متغیر مرجع (ارجاعی) یا یک ابرکلاس فراخوانی میشود. تعیین روش فراخوانی بر مبنای شیای است که توسط متغیر ارجاعی استفاده شده است.
تابع مجازی (Virtual Function)
تابع مجازی یک تابع عضو است که در یک کلاس پایه تعریف و توسط یک کلاس مشتق شده دوباره تعریف میشود (Overriden). وقتی با استفاده از یک اشارهگر یا ارجاع به کلاس پایه به یک شی کلاس مشتق شده مراجعه میکنید، میتوانید برای آن شی یک تابع مجازی فراخوانی کنید و نسخه تابع کلاس مشتق شده را اجرا کنید.
قواعد مربوط به یک تابع مجازی
• توابع مجازی باید عضوی از یک کلاس باشند.
• توابع مجازی نمیتوانند اعضای ایستا باشند.
• آنها از طریق اشارهگرهای شی قابل دسترسی هستند.
• آنها می توانند دوست یا کلاس دیگری باشند.
• یک تابع مجازی باید در کلاس پایه تعریف شود، حتا اگر از آن استفاده نشده باشد.
• نمونههای اولیه یک تابع مجازی از کلاس پایه و همه کلاسهای مشتق شده باید یکسان باشند.
• ما نمیتوانیم یک سازنده مجازی داشته باشیم، اما میتوانیم یک تخریبکننده مجازی داشته باشیم.
کلاسها (Classes)
کلاس یکی از مهمترین مفاهیم دنیای برنامهنویسی شیگرایی است. کلاسها در گوره نوعهای دادهای تعریف شده توسط کاربر طبقهبندی میشوند و شامل توابع و نوعهای دادهای خاص خود هستند. برنامهنویسان میتوانند با ساخت یک نمونه از یک کلاس به توابع و نوعهای دادهای یک کلاس دسترسی داشته باشند.
سازندهها
سازندهها نوع خاصی از اشیا عضو کلاس هستند که توسط کامپایلر زمانی فراخوانی میشوند که قرار است یک نمونه شی ساخته شده از کلاس ایجاد شود. سازندهها نام یکسانی با کلاس دارند و داخل یا خارج کلاس تعریف میشوند. در اینجا سه نوع سازنده به شرح زیر داریم:
1. سازنده پیشفرض
2. سازنده دارای پارامتر
3. سازنده کپی
سازندههای پیشفرض (Default constructors)
یک سازنده پیشفرض، سازندهای است که بدون هیچ آرگومان فراخوانی میشود.
سازنده پارامترداده شده (Parameterized constructors)
این امکان وجود دارد که پارامترهایی را به یک سازنده ارسال کرد. بهطور معمول، این آرگومانها در زمان ساخت شی برای مقداردهی آن استفاده میشوند. برای ساخت یک سازنده دارای پارامتر کافی است پارامترها را مشابه با زمان تعریف توابع برای سازنده مشخص کنید. زمانی که بدنه سازنده را تعریف میکنید از این پارامترها برای مقداردهی یک شی استفاده میکنید.
سازندههای کپی (Copy constructors)
یک سازنده کپی شی جدیدی ایجاد میکند که کپی یکسانی از شی موجود است. در این حالت کامپایلر یک سازنده کپی پیشفرض را برای تمامی کلاسها ارائه میکند. سازنده یک شی را با مقداردهی اولیه آن با یک شی از کلاس یکسانی ایجاد میکند که قبلا ایجاد شده است. سازنده کپی در موارد زیر استفاده میشود»
مقداردهی اولیه یک شی توسط شی دیگری که نوع یکسانی دارد.
کپی یک شی برای ارسال آن به عنوان آرگومان برای یک تابع
کپی یک شی برای بازگرداندن آن از یک تابع
اگر یک سازنده کپی توسط یک کلاس تعریف نشود، کامپایلر خودش آنرا تعریف میکند. اگر کلاس دارای متغیرهای اشارهگر و تخصیص پویای حافظه داشته باشد، ضروری است که سازنده کپی وجود داشته باشد. رایجترین اشکال یک سازنده کپی به شرح زیر هستند:
Classname (const classname *&obj) {//body of constructor
}
در قطعه کد بالا obj ارجاع به شیای دارد که برای مقداردهی اولیه شی دیگری استفاده شده است.
تخریبکنندهها
یک تخریبکننده تابع عضوی از یک کلاس است که بهطور خودکار زمانی که شی از دسترس خارج شد یا به شکل صریح تخریب شد فراخوانی میشود تا شی پاک شده و حافظه آزاد شود. تخریبکننده نام یکسانی با کلاس دارد با این تفاوت که یک پیشوند ~ دارد. بهطور مثال برای کلاس Destructor نام تابع یک تخریبکننده آن ~Destructor() است. اگر تخریبکنندهای را تعریف نکیند، کامپایلر بهطور پیشفرض آنرا ایجاد میکند. رویکرد فوق برای بیشتر کلاسها کافی است. شما تنها زمانی نیازمند تعریف یک تخریبکننده پیشفرض هستید که دستگیرده مربوط به منابع سیستمی را ذخیره کردهاید و لازم است این منابع دومرتبه به حافظه بازگردانده شوند. این موضوع در ارتباط با اشارهگرهایی که حافظه خاص خود را دارند نیز صدق میکند.
اشیا
یک شی نمونهای از یک کلاس است که شامل متدها و ویژگیهایی است که برای ساخت یک نوع خاص دادهای استفاده میشوند. هنگامی که پیامی برای یک شی ارسال میکنید، از شی درخواست میکنید که یکی از متدهای تعریف شده در کلاس را فراخوانی یا اجرا کند. از نقطه نظر برنامهنویسی یک شی میتواند شامل یک ساختار داده، یک متغیر یا یک تابع باشد که حافظهای به آن تخصیص داده شده است. این شی در قالب سلسله مراتب طبقاتی ایجاد میشود. کلاس یک طرح اولیه برای ساخت اشیا (یک ساختار داده خاص)، ارائه مقادیر اولیه برای وضعیت (متغیرهای عضو یا ویژگیها) و پیادهسازی رفتار (توابع یا روشهای عضو) است.
ماهنامه شبکه را از کجا تهیه کنیم؟
ماهنامه شبکه را میتوانید از کتابخانههای عمومی سراسر کشور و نیز از دکههای روزنامهفروشی تهیه نمائید.
ثبت اشتراک نسخه کاغذی ماهنامه شبکه
ثبت اشتراک نسخه آنلاین
کتاب الکترونیک +Network راهنمای شبکهها
- برای دانلود تنها کتاب کامل ترجمه فارسی +Network اینجا کلیک کنید.
کتاب الکترونیک دوره مقدماتی آموزش پایتون
- اگر قصد یادگیری برنامهنویسی را دارید ولی هیچ پیشزمینهای ندارید اینجا کلیک کنید.
نظر شما چیست؟