C++ Tutorial - part 71

آموزش جامع زبان برنامه‌نویسی C++ مقدماتی تا پیشرفته [0 تا 100 سی پلاس پلاس بهمراه حل تمرین و پروژه ✅] - شروع برنامه نویسی شی گرایی (OOP) - قسمت 71

مقدمه

شی‌گرایی یا Object-Oriented Programming (OOP) یک روش مدرن و قدرتمند برای طراحی و توسعه نرم‌افزارها است که با استفاده از کلاس‌ها و اشیاء، پیچیدگی‌های برنامه‌نویسی را مدیریت و ساده‌تر می‌کند. در این جلسه از آموزش زبان برنامه‌نویسی C++، قصد داریم به بررسی دقیق‌تر مفهوم شی‌گرایی بپردازیم و با مثال‌های کاربردی، این مفاهیم را برای شما روشن کنیم.

شی‌گرایی چیست؟

در دانشگاه‌ها، وقتی به درس‌های برنامه‌نویسی پیشرفته می‌رسید، معمولاً با مفاهیم شی‌گرایی یا OOP آشنا می‌شوید. اما متأسفانه این مباحث به دلیل آموزش نادرست و پیچیدگی‌های غیرضروری، برای بسیاری از دانشجویان تبدیل به مفاهیمی سرد و بی‌روح می‌شود که انگیزه یادگیری را از بین می‌برد. هدف ما در این جلسه این است که با یک روش ساده و قابل فهم، لذت یادگیری شی‌گرایی را به شما برگردانیم.

برنامه‌نویسی رویه‌ای (Procedural Programming)

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

مشکلات برنامه‌نویسی رویه‌ای

  1. پیوستگی و وابستگی توابع:
    • در برنامه‌های بزرگ، تغییر یک تابع ممکن است باعث بروز خطا در سایر توابع شود که این امر مدیریت و نگهداری کد را دشوار می‌کند.
  2. عدم مدیریت داده‌ها:
    • داده‌ها در سراسر برنامه پراکنده هستند و کنترل دسترسی به آنها مشکل است. این امر می‌تواند منجر به بروز خطاهای امنیتی و عدم یکپارچگی داده‌ها شود.

شی‌گرایی: راه‌حل مشکلات برنامه‌نویسی رویه‌ای

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

اصول شی‌گرایی

شی‌گرایی چهار اصل اساسی دارد که هر یک به نحوی به مدیریت پیچیدگی‌ها و بهبود ساختار برنامه کمک می‌کنند:

1. کپسوله‌سازی (Encapsulation)

کپسوله‌سازی به معنای پنهان‌سازی جزئیات پیاده‌سازی و نمایش واسط ساده به کاربر است. در این اصل، داده‌ها و توابع مرتبط در یک کلاس قرار می‌گیرند و از طریق متدهای عمومی (public) در دسترس قرار می‌گیرند. این امر باعث می‌شود تا جزئیات پیاده‌سازی پنهان بماند و تنها واسط‌های ضروری برای کاربر قابل مشاهده باشد.

2. وراثت (Inheritance)

وراثت امکان ایجاد کلاس‌های جدید بر اساس کلاس‌های موجود را فراهم می‌کند. این امر باعث می‌شود تا بتوانیم ویژگی‌ها و رفتارهای مشترک را در یک کلاس پایه تعریف کرده و کلاس‌های فرزند از آن استفاده کنند. این اصل باعث کاهش تکرار کد و افزایش قابلیت استفاده مجدد می‌شود.

3. چندریختی (Polymorphism)

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

4. انتزاع (Abstraction)

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

کلاس و شیء در شی‌گرایی

تعریف کلاس

کلاس‌ها قالب‌هایی هستند که ویژگی‌ها (Properties) و رفتارها (Methods) را تعریف می‌کنند. یک کلاس می‌تواند شامل متغیرها و توابعی باشد که مرتبط با یک مفهوم خاص هستند. به عنوان مثال، کلاس Car می‌تواند ویژگی‌هایی مانند brand، model و year و رفتارهایی مانند start و stop داشته باشد.

تعریف شیء

شیء یک نمونه واقعی از یک کلاس است که دارای ویژگی‌ها و رفتارهای تعریف‌شده در کلاس می‌باشد. به عنوان مثال، myCar یک شیء از کلاس Car است که می‌تواند ویژگی‌ها و رفتارهای تعریف‌شده در کلاس را دارا باشد.

مثال عملی از شی‌گرایی (نیازی به فهم ساختار سورس کد نیست)

فرض کنید می‌خواهیم یک برنامه برای مدیریت ماشین‌ها بنویسیم. ابتدا یک کلاس به نام Car ایجاد می‌کنیم و ویژگی‌ها و رفتارهای آن را تعریف می‌کنیم:

				
					#include <iostream>
using namespace std;

class Car {
public:
    string brand;
    string model;
    int year;

    void start() {
        cout << "Car is starting..." << endl;
    }

    void stop() {
        cout << "Car is stopping..." << endl;
    }
};

int main() {
    Car myCar;
    myCar.brand = "Toyota";
    myCar.model = "Corolla";
    myCar.year = 2020;

    cout << "Brand: " << myCar.brand << endl;
    cout << "Model: " << myCar.model << endl;
    cout << "Year: " << myCar.year << endl;

    myCar.start();
    myCar.stop();

    return 0;
}

				
			

در این مثال، ما یک کلاس به نام Car تعریف کرده‌ایم که دارای ویژگی‌های brand، model و year و همچنین رفتارهای start و stop است. سپس یک شیء به نام myCar از این کلاس ایجاد کرده و ویژگی‌ها و رفتارهای آن را استفاده می‌کنیم.

مزایای شی‌گرایی

1. مدیریت بهتر پیچیدگی

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

2. قابلیت استفاده مجدد

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

3. امنیت داده‌ها

با استفاده از دسترسی‌های خصوصی (private) و محافظت‌شده (protected)، می‌توان دسترسی به داده‌ها را کنترل کرد و از تغییرات ناخواسته جلوگیری نمود. این امر باعث افزایش امنیت و یکپارچگی داده‌ها می‌شود.

4. پشتیبانی از مفاهیم دنیای واقعی

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

مفاهیم پیشرفته در شی‌گرایی

1. سازنده‌ها و مخرب‌ها (Constructors and Destructors)

(نیازی به فهم ساختار سورس کد نیست)

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

				
					#include <iostream>
using namespace std;

class Car {
public:
    string brand;
    string model;
    int year;

    // سازنده
    Car(string b, string m, int y) {
        brand = b;
        model = m;
        year = y;
    }

    // مخرب
    ~Car() {
        cout << "Car object is destroyed." << endl;
    }

    void start() {
        cout << "Car is starting..." << endl;
    }

    void stop() {
        cout << "Car is stopping..." << endl;
    }
};

int main() {
    Car myCar("Toyota", "Corolla", 2020);

    cout << "Brand: " << myCar.brand << endl;
    cout << "Model: " << myCar.model << endl;
    cout << "Year: " << myCar.year << endl;

    myCar.start();
    myCar.stop();

    return 0;
}

				
			

در این مثال، سازنده Car وظیفه دارد تا ویژگی‌های brand، model و year را مقداردهی اولیه کند و مخرب Car وظیفه دارد تا هنگام از بین رفتن شیء، پیامی را نمایش دهد.

2. وراثت   (Inheritance)

(نیازی به فهم ساختار سورس کد نیست)

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

				
					#include <iostream>
using namespace std;

class Vehicle {
public:
    string brand;

    void honk() {
        cout << "Beep beep!" << endl;
    }
};

class Car : public Vehicle {
public:
    string model;
    int year;

    void start() {
        cout << "Car is starting..." << endl;
    }

    void stop() {
        cout << "Car is stopping..." << endl;
    }
};

int main() {
    Car myCar;
    myCar.brand = "Toyota";
    myCar.model = "Corolla";
    myCar.year = 2020;

    cout << "Brand: " << myCar.brand << endl;
    cout << "Model: " << myCar.model << endl;
    cout << "Year: " << myCar.year << endl;

    myCar.honk();
    myCar.start();
    myCar.stop();

    return 0;
}

				
			

در این مثال، کلاس Car از کلاس Vehicle ارث‌بری کرده و از ویژگی‌ها و رفتارهای آن استفاده می‌کند.

3. چندریختی  (Polymorphism)

(نیازی به فهم ساختار سورس کد نیست)

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

				
					#include <iostream>
using namespace std;

class Vehicle {
public:
    virtual void honk() {
        cout << "Beep beep!" << endl;
    }
};

class Car : public Vehicle {
public:
    void honk() override {
        cout << "Car is honking: Beep beep!" << endl;
    }
};

class Bike : public Vehicle {
public:
    void honk() override {
        cout << "Bike is honking: Beep beep!" << endl;
    }
};

void makeHonk(Vehicle* v) {
    v->honk();
}

int main() {
    Car myCar;
    Bike myBike;

    makeHonk(&myCar);
    makeHonk(&myBike);

    return 0;
}

				
			

در این مثال، تابع makeHonk از واسط مشترک Vehicle استفاده می‌کند تا بتواند با اشیاء Car و Bike به صورت یکسان تعامل کند و هر یک از آنها متد honk خود را اجرا کنند.

4. انتزاع (Abstraction)

(نیازی به فهم ساختار سورس کد نیست)

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

				
					#include <iostream>
using namespace std;

class Vehicle {
public:
    virtual void honk() = 0; // متد انتزاعی
};

class Car : public Vehicle {
public:
    void honk() override {
        cout << "Car is honking: Beep beep!" << endl;
    }
};

class Bike : public Vehicle {
public:
    void honk() override {
        cout << "Bike is honking: Beep beep!" << endl;
    }
};

int main() {
    Car myCar;
    Bike myBike;

    myCar.honk();
    myBike.honk();

    return 0;
}

				
			

در این مثال، کلاس Vehicle یک کلاس انتزاعی است که دارای متد انتزاعی honk می‌باشد. کلاس‌های Car و Bike این متد را پیاده‌سازی می‌کنند و از طریق واسط مشترک Vehicle، این متدها قابل فراخوانی هستند.

نتیجه‌گیری

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

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

منابع خارجی مرتبط 

ادامه دوره (قسمت 72)

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

در این قسمت، قصد داریم نحوه ارسال و دریافت آرایه دو بعدی به/از تابع در زبان برنامه‌نویسی C++ را مورد بررسی قرار دهیم. برای این کار...

در قسمت قبل، با دو پارادایم برنامه‌نویسی اصلی، یعنی پروسیجرال (Procedural) و شی‌گرایی (Object-Oriented Programming) آشنا شدیم. متوجه شدیم که...

شروع برنامه نویسی شی گرایی (OOP)

حق کپی ویدئو مجاز نمی‌باشد

قسمت:

جلسه هفتاد و یک

نام دوره:

آموزش جامع ++C

زمان ویدئو:

24 دقیقه

مدرس:

مهدی کاظمی

در این قسمت یادخواهید گرفت:

شی‌گرایی یا Object-Oriented Programming (OOP) یک روش مدرن و قدرتمند برای طراحی و توسعه نرم‌افزارها است که با استفاده از کلاس‌ها و اشیاء، پیچیدگی‌های برنامه‌نویسی را مدیریت و ساده‌تر می‌کند. در این جلسه از آموزش زبان برنامه‌نویسی C++، قصد داریم به بررسی دقیق‌تر مفهوم شی‌گرایی بپردازیم و با مثال‌های کاربردی، این مفاهیم را برای شما روشن کنیم.

مهدی کاظمی

سلام مهدی کاظمی هستم و باعث افتخارم هست که در یک دوره جذاب دیگه با شما هستم و قراره در کنار هم از یادگیریمون لذت ببریم.

با بانک سوالات طبقه بندی شده ++C مقدماتی تا پیشرفته، جامع ترین منبع برای تسلط بر زبان سی پلاس پلاس و آمادگی کامل برای دروس مبانی و پیشرفته کامپیوتر در رشته مهندسی کامپیوتر را در اختیار خواهید داشت.

0 دیدگاه
بازخورد (Feedback) های اینلاین
مشاهده همه دیدگاه ها