اگر تازه برنامه نویسی را شروع کرده‌اید، و با مقدمات برنامه نویسی آشنا نیستید، پیشنهاد می‌کنم از خواندن این مقاله صرف نظر کنید. مطالبی که درباره برنامه نویسی شی گرا، مطالبی بسیار آسان و شیرین هستند به شرطی که شما مبانی ابتدایی برنامه نویسی را بلد باشید. اگر تجربه برنامه نویسی داشته‌اید و حالا قصد دارید سطح خود را ارتقا دهید، این مقاله برای شما مناسب است. همچنین اگر با این مطالب آشنایی دارید، به شما کمک خواهد کرد تا مروری بر این اطلاعات پایه‌ایی داشته باشید. همانطور که می‌دانید هرچه بر اطلاعات پایه‌ایی اشراف بیشتری داشته باشید، راحت‌تر پیشرفت خواهید کرد.

مطابی را که در این مقاله بررسی خواهیم کرد:

تعریف برنامه نویسی شی گرا

برنامه نویسی شی گرا (Object Oriented Programming) یا به اختصار OOP یک نوع مدل برنامه نویسی است. این مدل برنامه نویسی بر پایه کلاس و شی می‌باشد. هر شی یک سری خصوصیات (Property) و یک سری رفتارها (Method) دارد. این الگو را در جهان واقعی نیز می‌توان پیدا کرد. مثلا یک ماشین را به عنوان شی در نظر بگیرید. این ماشین یک سری خصوصیات از قبیل رنگ، وزن، سرعت، سوخت و … دارد. هر کدام از این خصوصیات مقادیر خاص خود را دارند. مثلا رنگ آن آبی، وزن آن یک تُن و مثلا سرعت آن در حال حاضر ۰ می‌باشد. همچنین این شی یک سری رفتارهایی را دارد که روی خصوصیات آن تاثیرگذار است. برای مثال، یکی از رفتارهای این ماشین گاز دادن است که مستقیم روی ویژگی سرعت تاثیر می‌گذارد. با هربار گاز دادن سرعت ماشین افزایش می‌یابد (البته به شرطی که ماشین خلاص باشد:)).

دقت داشته باشید که به خصوصیات یک کلاس، پراپرتی، متغیر، فیلد و … می‌گویند. همچنین به رفتارهای یک کلاس، متد می‌گویند. پس در ادامه اگر هرکدام از این اسامی را دیدید، سردرگم نشوید.

تفاوت کلاس (Class) و شی (Object) چیست؟

کلاس یک طرح کلی است که اشیاء از روی آن ساخته می‌شوند. برای درک بهتر به این مثال توجه کنید. ما نقشه یک خانه را طراحی می‌کنیم و سپس ممکن است چندین خانه را با این نقشه بسازیم. هنگامی که نقشه را طراحی کردیم، هزینه‌های اجرایی برای ما ندارد. ولی هنگامی که خانه را شروع به ساختن می‌کنیم هزینه‌هایی برای ما خواهد داشت. در برنامه نویسی هم به همین شکل است. وقتی شما در حال تعریف کلاس هستید (تعریف نقشه)، هیچ هزینه‌ای برای شما ندارد ولی به محض اینکه اولین شی را از روی کلاس ساختید، برای شما هزینه خواهد داشت. شاید از خود بپرسید که ساختن یک شی چه هزینه‌ایی برای ما دارد؟ در اینجا منظور از هزینه، استفاده از منابع کامپیوتر (RAM،CPU و …) است. هر شی مقداری از رم کامپیوتر را مورد استفاده قرار خواهد داد.

لطفا به قطعه کد زیر دقت کنید:

public class Car
}
;double speed    
;double fuel    
;string color    

()public double getFuel    
}    
;return fuel      
{    
(double fu)public void setFuel    
}    
;fuel = fu      
{    
{

چگونه کلاس و شی تعریف کنیم؟

کد بالا با زبان سی شارپ نوشته شده است. همانطور که مشاهده می‌کنید ابتدا یک کلاس با نام Car تعریف کرده‌ایم. این کلاس سه ویژگی (Property) دارد (speed, fuel, color). همانطور که از اسم این فیلدها مشخص است سرعت، بنزین و رنگ ماشین را مشخص می‌کنند. در ادامه دو رفتار (Method) تعریف کرده‌ایم. همانطور که گفتیم، متدها روی ویژگی‌ها تاثیر می‌گذارند. با متد setFuel می‌توانید پارمتری را بفرستید تا مقدار پراپرتی fuel تغییر کند. همچنین شما می‌توانید با متد getFuel مقدار بنزین این ماشین را بدست آورید. با کد بالا شما طرح کلی یک ماشین را تعریف کرده‌اید. حالا برای ساختن آبجکت از روی این ماشین کافیست به شکل زیر عمل کنیم:

;()Car car1 = new Car

به خاطر داشته باشید، برای استفاده از یک کلاس، باید از روی آن یک شی بسیازیم. با استفاده از شی به کلاس دسترسی خواهیم داشت.

 

شاید از خود بپرسید که اصلا ما چه نیازی به برنامه نویسی شی گرا داریم؟ چرا اصلا کلاس تعریف کنیم؟ وقتی در حال طراحی یک اپلیکیشن، سایت و … هستید، بهتر است از کلاس‌ها استفاده کنید. با این کار شما می‌توانید برنامه را به قسمت‌های مختلف تقسیم کنید. فرض کنید یک وبسایت فروش کالا را می‌خواهید طراحی کنید. شما می‌توانید کلاس‌هایی را برای انجام امور مختلف بسازید. مثلا یک کلاس برای ثبت نام، یک کلاس برای لاگین، یک کلاس برای فروش محصولات، یک کلاس برای ارتباط با دیتابیس و …

چرا به شی گرایی (OOP) نیاز داریم؟

 

شاید از خود بپرسید که اصلا ما چه نیازی به برنامه نویسی شی گرا داریم؟ چرا اصلا کلاس تعریف کنیم؟ وقتی در حال طراحی یک اپلیکیشن، سایت و … هستید، بهتر است از کلاس‌ها استفاده کنید. با این کار شما می‌توانید برنامه را به قسمت‌های مختلف تقسیم کنید. فرض کنید یک وبسایت فروش کالا را می‌خواهید طراحی کنید. شما می‌توانید کلاس‌هایی را برای انجام امور مختلف بسازید. مثلا یک کلاس برای ثبت نام، یک کلاس برای لاگین، یک کلاس برای فروش محصولات، یک کلاس برای ارتباط با دیتابیس و …

اصطلاحات برنامه نویسی شی گرا

تغییر دهنده دسترسی (Access Modifier)

 

Access Modifiers در برنامه نویسی شی گرا کلماتی هستند که سطح دسترسی به کلاس‌ها، متدها، خصوصیات و … را تنظیم می‌کنند. در زبان سی شارپ Access Modifier‌ مختلفی وجود دارد از قبیل Public ,Private ,Internal ,Protected و … در این مقاله به بررسی Public و Private که کاربرد بیشتری نسبت به بقیه دارند می‌پردازیم.

Public

این کلمه در ابتدای تعریف کلاس‌ها، متدها و فیلدها می‌آید و مشخص می‌کند که سطح دسترسی آن‌ها عمومی باشد. یک متد اگر Public باشد، از درون کلاس‌های دیگر قابل دسترسی خواهد بود. به عنوان مثال:

public class Car
}
;public double speed    
 {

class Program
}
static void Main(string[] args)    
}    
;()Car car = new Car      
;car.speed = 20      
Console.WriteLine(car.speed); //this line will return 20      
{    
{

Private

اگر یک متد، یا یک فیلد با استفاده از این کلمه تعریف شود، از سایر کلاس‌ها قابل دسترسی نخواهد بود و فقط در داخل همان کلاس قابل نمایش است.

public class Car
}
;private double speed    
{
class Program
}
static void Main(string[] args)    
}    
;()Car car = new Car      
car.speed = 20; //error: car.speed is inacessiable due to its protection level      
{    
{

کد بالا با خطا مواجه شده و کامپایل نخواهد شد. به دلیل این که فیلد speed درون کلاس Car به صورت Private تعریف شده است. به همین خاطر از کلاس‌ Program به این فیلد دسترسی نخواهیم داشت.

Encapsulation

کپسوله سازی

به بسته بندی فیلدها و متدها در یک واحد یکتا Encapsulation یا کپسوله سازی می‌گویند. در کپسوله سازی، متغیرهای یک کلاس از دید سایر کلاس‌ها مخفی می‌شوند و فقط از طریق متدهایی که برای آنها تعریف می‌کنیم قابل دسترسی هستند. اگر با شی گرایی کمی آشنا باشید می‌دانید که به این متدها Setter, Getter می‌گویند. برای پیاده سازی Encapsulation دو مرحله زیر را باید طی کنیم:

  1. متغیرهای مدنظرمان را به صورت Private تعریف کنیم تا در داخل همان کلاس قابل دسترسی باشند.
  2. متدهای Setter, Getter را برای نمایش و ویرایش مقادیر این متغیرها تعریف کنیم

به مثال زیر توجه کنید:

public class Car
}
;private double speed    
;private string color    
()public double getSpeed    
}    
;return speed      
{    
(double speed1)public void setSpeed     
}    
;speed = speed1      
{    
()public string getColor    
}    
;return color      
{    
(string color1)public void setColor    
}    
;color = color1      
{    
 {

Encapsulation باعث می‌شود تا برای دسترسی به فیلدها مجبور باشیم از متدها استفاده کنیم. بنابراین از هرگونه تغییرات ناخواسته فیلدها جلوگیری به عمل خواهد آمد.

Inheritance

ارث بری

در بیولوژی (زیست شناسی) مفهومی تحت عنوان ارث‌بری وجود دارد. هر فرزند از والد خود یک سری ویژگی‌ها را به ارث می‌برد. دقیقا همانند این مفهوم در برنامه نویسی نیز وجود دارد. یک کلاس می‌تواند از یک کلاس دیگر ارث بری کند. ارث بری باعث می‌شود که در یک کلاس، بتوانید از فیلدها و متدهایی که قبلا در کلاس دیگر تعریف کرده‌اید، استفاده کنید. کلاس والد را Super Class و کلاسی که ارث بری انجام می‌دهد را Derived Class یا Sub Class گویند. برای پیاده سازی ارث بری در سی شارپ کافی است که بعد از نام کلاس یک ” : ” بگذارید و نام کلاسی که می‌خواهید از آن ارث برده شود را بنویسید. به مثال زیر دقت کنید.

public class Car
}
()public void getDetails    
}    
پیاده سازی//    
{    
{

public class Lamborghini : Car
}    
پیاده سازی //    
{    
public class Program
}
(string[] args) static void Main    
}    
;()Lamborghini lamb = new Lamborghini      
;()lamb.getDetails      
{    
{

Polymorphism

چندریختی

پلی مورفیسم (چندریختی) مربوط به انجام دادن یک کار به شکل‌های مختلف می‌باشد. دو نوع چند ریختی وجود دارد که در ادامه به آنها خواهیم پرداخت:

این نوع چند ریختی از طریق Method Overloading به دست می‌آید. منظور از Method Overloading این است که چند متد در یک کلاس با یک نام وجود داشته باشند ولی پارامترهای آنها، نوع، ترتیب یا تعداد مختلفی داشته باشند.

public class Division
}
static int division(int x, int y)    
}    
  ;return x + y      
{    

static double division(double x, double y)    
}    
  ;return x + y      
{    
{

گاهی اوقات شرایطی پیش می‌آید که در کلاس والد و فرزند، دو متد هم نام داشته باشید که هرکدام پیاده سازی خاص خودشان را دارند. به این کار Method Overriding می‌گویند فرض کنید دوتا کلاس دارید، یکی والد و دیگری فرزند (کلاس فرزند از کلاس والد ارث بری می‌کند). در کلاس والد یک متد دارید با نام decreaseFuel. حالا در کلاس فرزند نیز یک متد با همین نام درست می‌کنید. در حالی که بدنه این متد در کلاس فرزند با بدنه آن در کلاس والد تفاوت دارد. کلاس فرزند می‌تواند متدی که در کلاس والد نیز وجود دارد را به صورت متفاوتی پیاده سازی کند. متدی که ممکن است نیاز به بازنویسی داشته باشد را باید با کلمه virtual نشانه گذاری کرد. همچنین برای بازنویسی متد در کلاس فرزند، از کلمه override باید استفاده کرد. به مثال زیر توجه کنید:

public class Car
}
()public virtual void decreaseFuel    
}    
;Console.WriteLine("Decreasing...")      
{    
{
public class Ford: Car
}
()public override void decreaseFuel    
}    
;int fuel      
;Console.WriteLine("Decreasing"+fuel)      
{    
{

public class TestOverriding
}
()public static void Main    
}    
;()Dog d = new Dog      
;()d.eat      
{    
{

Abstraction

انتزاعی

 

به مخفی کردن پیچیدگی‌ و جزئیات از کاربر Abstraction می‌گویند. کاربر فقط باید ظاهر کار را ببیند و متوجه پیچیدگی که در پشت سیستم وجود دارد نشود. به عنوان مثال کاربر فقط باید بداند که با زدن دکمه Shutdown سیستم خاموش خواهد شد. این که چه روندی طی می‌شود تا سیستم خاموش شود، از دید کاربر مخفی است. در سی شارپ Abstraction توسط Abstract Class و Interface بدست می‌آید. در مقالات بعدی به تفاوت‌های Abstract Class و Interface خواهیم پرداخت.

Abstract Class

قبل از توضیح Abstract Class ابتدا باید به مفهوم کلمه Abstract بپردازیم. Abstract در فارسی به معنای انتزاع، مفهوم و برداشت است. منظور از انتزاع چیست؟ انتزاع طرح و تصویر کلی است که در ذهن ما وجود دارد. برای اینکه مفهوم انتزاع را بهتر درک کنید به این مثال توجه کنید. در دنیای واقعی کلمه “خزنده” را در نظر بگیرید. خزنده یک موجود نیست، یعنی خود خزنده یک موجود زنده نیست بلکه یک طرح کلی است از حیواناتی که می‌خزند مانند مار، لاکپشت و … یا مثلا درخت را در نظر بگیرید، خود درخت وجود خارجی ندارد. یعنی وقتی اسم درخت به میان می‌آید، هر کس یک تصویر از درخت می‌کند. یکی درخت سیب را تصور می‌کند یکی درخت پرتقال و …

Abstract Class یک دید انتزاعی است. مثلا فرض کنید یک Class تعریف کرده‌اید تحت عنوان Animal (حیوان). این کلاس یک متد دارد تحت عنوان Eat (غذا خوردن). شما نمی‌توانید داخل این متد عادت‌های غذایی تمام حیوانات را در نظر بگیرید. چون هر کدام غذاهای مختلفی به میزان مختلفی نیاز دارند. این موضوع به این خاطر است که حیوان یک دید انتزاعی است و وجود خارجی ندارد. حیوانات مختلف مانند سگ، کبوتر، گوسفند و … هرکدام غذای خاص خودشان را می‌خورند بنابراین شما مجبور هستید متد Eat را فقط نامگذاری کنید ولی در بدنه آن هیچ کدی ننویسید. به این گونه متدها که تعریف شده ولی پیاده سازی نشده‌اند Abstract Method گفته می‌شود. از روی کلاس‌های Abstract نمی‌توان شی ساخت، زیرا همانطور که گفتیم، کلاس‌های انتزاعی وجود خارجی ندارند. برای استفاده از کلاس‌های Abstract باید از روی آن‌ها ارث بری کنید و سپس از روی کلاس فرزند، آبجکت بسازید.

  public abstract class Car
}
;()public abstract void Brake    
{
public abstract class Lamborghini : Car
}
()public override void Brake    
}    
پیاده سازی //    
{    
{
 class Program
    }
        static void Main(string[] args)    
        }    
;()Lamborghini lamb = new Lamborghini      
;()lamb.Brake      
        {    
    {

نتیجه گیری

شما می‌توانید همه کدهای خود را پشت سرهم به صورت رویه‌ای بنویسید. ولی به مرور زمان با افزایش کدها و پیچیدگی پروژه نگهداری، رفع باگ و تعمیرات بسیار مشکل خواهد بود. با استفاده از OOP حجم کدهای شما کمتر خواهد شد به این دلیل که شما می‌توانید یک کد را چندبار استفاده کنید. قطعا وقتی کدهای خود را در کلاس‌های جداگانه بنویسید پیدا کردن مشکل بسیار آسان‌تر خواهد بود.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *