کلاس (برنامه‌نویسی)

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

کلاس یک انتزاع است که به توسعه‌دهندگان کمک می‌کند تا مدل‌های دنیای واقعی را به برنامه تبدیل کنند. کلاس‌ها شامل دو عنصر اصلی هستند:
* داده‌ها یا صفات: خصوصیات یا متغیرهایی که ویژگی‌های یک شیء را تعریف می‌کنند.
* عملیات یا روش‌ها: توابعی که رفتارهای شی را مشخص می‌کنند.

**مثال در Java:**
```java
public class Car {
    String brand;
    int year;

    void drive() {
        System.out.println("Driving the car");
    }
}
```


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

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

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

مثال: رانندگی خودرو بدون اطلاع از خصوصیات طرز کار داخلی موتور و سیستم‌های اگزوز و جعبه‌دنده امکان‌پذیر است. در مهندسی نرم‌افزار ضرورت پنهان‌سازی اطلاعات امری بسیار مهم هست. 

در زبان‌های رویه‌ای برنامه‌نویسی، مثل زبان سی (C)، برنامه‌نویسی، بیشتر عملگرایانه است. درحالی‌که، زبان‌های برنامه‌نویسی سی‌پلاس‌پلاس (++C)، جاوا (Java)، و سی‌شارپ (#C) دارای پارادایم شی‌گرایانه هستند. واحد برنامه‌نویسی در زبان‌های رویه‌ای تابع است، ولی، زبان‌های شی‌گرا دارای کلاس‌ها - که اشیا نهایتاً از آنها ایجاد می‌شوند (یا اصطلاحاً نمونه‌سازی می‌شوند) - به عنوان واحد برنامه‌نویسی هستند. توابع نیز در داخل کلاس‌ها به عنوان متدهایی پیاده‌سازی می‌شوند.

برنامه‌نویسان C، بیشتر بر روی نوشتن توابع متمرکز هستند. گروه‌هایی از اعمال که وظیفهٔ خاصی را بر عهده دارند، توابع را تشکیل می‌دهند و توابع گروه شده و برنامه را تشکیل می‌دهند. البته در زبان c داده‌ها نیز مهم هستند، اما نگرش اصلی در اینگونه زبان‌ها این است که داده‌ها بیشتر برای پشتیبانی اعمالی که توابع انجام می‌دهند به کار می‌روند.

## اجزای کلاس
کلاس‌ها از چندین جزء اصلی تشکیل شده‌اند که در این بخش به تفصیل به هر یک می‌پردازیم:

* **صفات (Attributes):**
** متغیرهایی که ویژگی‌های یک شیء را مشخص می‌کنند. به‌عنوان مثال، یک کلاس Car ممکن است صفاتی مانند brand، color و year داشته باشد.
** صفات می‌توانند خصوصی (private) یا عمومی (public) باشند.
* **متدها (Methods):**
** توابعی که در کلاس تعریف می‌شوند و وظایف مرتبط با شیء را انجام می‌دهند.
** متدها می‌توانند شامل عملیات‌هایی مانند افزودن، حذف یا نمایش داده‌ها باشند.
* **سازنده‌ها (Constructors):**
** توابع خاصی که هنگام ایجاد یک شیء جدید از کلاس فراخوانی می‌شوند.
** وظیفه سازنده، مقداردهی اولیه صفات کلاس است.
* **ویرانگرها (Destructors):**
** توابع خاصی که زمانی که شیء از بین می‌رود، فراخوانی می‌شوند.
** این توابع در زبان‌هایی مانند C++ برای آزادسازی منابع استفاده می‌شوند.

## کپسوله‌سازی (Encapsulation)
کپسوله‌سازی یکی از اصول بنیادی برنامه‌نویسی شیءگرا (Object-Oriented Programming) است که هدف آن **مخفی‌سازی جزئیات داخلی یک شیء** و فراهم‌سازی یک **رابط کنترل‌شده و امن** برای تعامل با آن است. این اصل از طریق **محدود کردن دسترسی مستقیم به فیلدهای داخلی کلاس** و ارائه متدها یا پراپرتی‌هایی برای دسترسی غیرمستقیم، اجرا می‌شود.

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

#### مزایا

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

#### مثال در زبان‌های مختلف
**Python (با استفاده از متدهای getter و setter):**


```python
class Car:
    def __init__(self, brand, year):
        self.__brand = brand  
        self.__year = year

    def get_brand(self):
        return self.__brand

    def set_brand(self, brand):
        self.__brand = brand
```
C# (با استفاده از پراپرتی‌ها):
```c#
public class Employee
{
    private int _age;

    public int Age 
    {
        get { return _age; }
        set 
        {
            if (value > 0 && value < 120)
                _age = value;
            else
                Console.WriteLine("سن نامعتبر است.");
        }
    }
}
```
در مثال بالا، پراپرتی `Age` واسطه‌ای بین کد بیرونی و فیلد داخلی `_age` فراهم می‌کند. در نتیجه، مقداردهی به متغیر تنها در صورت اعتبارسنجی موفق انجام می‌گیرد.

همچنین در C# می‌توان پراپرتی‌های فقط‌خواندنی (Read-Only) یا محاسباتی تعریف کرد، مانند:
```c#
public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public string FullName => $"{FirstName} {LastName}";
}
```
در اینجا پراپرتی `FullName` فقط قابل خواندن است و هر بار به‌صورت داینامیک محاسبه می‌شود.

## وراثت (Inheritance)
وراثت یکی از مفاهیم کلیدی در شیءگرایی است که به یک کلاس اجازه می‌دهد ویژگی‌ها و رفتارهای یک کلاس دیگر را به ارث ببرد.

**انواع وراثت:**

* **وراثت تک‌سطحی (Single Inheritance):** یک کلاس فقط از یک کلاس دیگر ارث می‌برد.
* **وراثت چندسطحی (Multi-level Inheritance):** یک کلاس از کلاسی که خود از کلاس دیگری ارث برده است، ارث می‌برد.
* **وراثت چندگانه (Multiple Inheritance):** یک کلاس از چندین کلاس ارث می‌برد (در برخی زبان‌ها مانند Python ممکن است).

**مثال در Python (وراثت چندگانه):**
```python
class Vehicle:
    def move(self):
        print("Moving")

class Car(Vehicle):
    def drive(self):
        print("Driving")

myCar = Car()
myCar.move()  # Inherited method
myCar.drive()  # Specific method
```


## چندریختی (Polymorphism)
چندریختی یکی از اصول اساسی برنامه‌نویسی شیءگرا است که به اشیاء اجازه می‌دهد بسته به نوع خود، رفتارهای مختلفی داشته باشند. واژه *چندریختی* به معنای "چند شکل داشتن" است و در برنامه‌نویسی به توانایی یک مرجع (مانند متغیر یا اشاره‌گر) برای نشان دادن رفتارهای متفاوت در شرایط مختلف اشاره دارد.

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

#### چندریختی در زمان کامپایل (Compile-Time Polymorphism):
این نوع چندریختی که *چندریختی استاتیک* نیز نامیده می‌شود، شامل اورلودینگ (Overloading) و استفاده از پارامترهای متفاوت برای متدها یا توابع است. در این حالت، انتخاب متد یا تابع مناسب در زمان کامپایل صورت می‌گیرد.

مثال:

در یک زبان مانند ++C، می‌توان چند نسخه از یک تابع با نام یکسان تعریف کرد که پارامترهای متفاوتی دریافت می‌کنند:
```c++
class Math {
public:
    int add(int a, int b) {
        return a + b;
    }
    double add(double a, double b) {
        return a + b;
    }
};
```


#### '''چندریختی در زمان اجرا (Run-Time Polymorphism):'''
این نوع چندریختی که به آن *چندریختی پویا* نیز گفته می‌شود، از طریق ارث‌بری و استفاده از توابع مجازی (Virtual Functions) یا متدهای سربار (Overridden Methods) حاصل می‌شود. در این حالت، تصمیم‌گیری درباره انتخاب متد مناسب در زمان اجرا انجام می‌گیرد.

**مثال:**
```c++
class Shape {
public:
    virtual void draw() {
        std::cout << "Drawing a shape" << std::endl;
    }
};

class Circle : public Shape {
public:
    void draw() override {
        std::cout << "Drawing a circle" << std::endl;
    }
};

class Rectangle : public Shape {
public:
    void draw() override {
        std::cout << "Drawing a rectangle" << std::endl;
    }
};

int main() {
    Shape* shape1 = new Circle();
    Shape* shape2 = new Rectangle();

    shape1->draw(); // خروجی: Drawing a circle
    shape2->draw(); // خروجی: Drawing a rectangle

    delete shape1;
    delete shape2;

    return 0;
}
```
چندریختی با ارائه انعطاف‌پذیری و توسعه‌پذیری بالا، امکان استفاده از یک رابط عمومی برای انواع مختلف اشیاء را فراهم می‌کند، اما ممکن است به دلیل پیچیدگی درک و افت عملکرد در پروژه‌های بزرگ چالش‌هایی ایجاد کند. این ویژگی در زبان‌هایی مانند Java، C++، Python و C# از طریق ارث‌بری و سربارکردن متدها پیاده‌سازی می‌شود.

## زبان‌های برنامه‌نویسی شیءگرا و کلاس‌ها
زبان‌های مختلف برنامه‌نویسی شیءگرا مانند Java، C++، C#، و Python از کلاس‌ها استفاده می‌کنند.

تفاوت‌ها در نحوه تعریف و استفاده از کلاس‌ها در این زبان‌ها:

* در C++، کنترل دستی بیشتری بر حافظه داریم.
* در Python، تعریف کلاس ساده‌تر و انعطاف‌پذیرتر است.
* در Java، مفاهیمی مانند کپسوله‌سازی و وراثت به‌طور کامل پیاده‌سازی شده است.

## پانوشته‌ها

## جستارهای وابسته
* برنامه‌نویسی اشیاءنگر
* هستی‌شناسی (علوم محاسباتی)

## پیوند به بیرون
* مفاهیم مربوط به برنامه‌نویسی اشیاءنگر

## منابع
* برنامه‌نویسی به زبان C++، تألیف عین‌الله جعفرنژاد قمی
* Visual C++ .NET برای برنامه‌نویسان پیشرفته
* جاوا: چگونه آن را برنامه‌نویسی کنیم (چاپ هفتم) (انگلیسی)
* کپسوله‌سازی در C# - LearnClasico


رده:کلاس (برنامه‌نویسی)
رده:برنامه‌نویسی شیءگرا
رده:ساختارهای برنامه‌نویسی
رده:موضوعات مربوط به زبان‌های برنامه‌نویسی