اصول کپسوله‌سازی و انتزاع

اصلاح شده

2026-07-25

کپسوله‌سازی (Encapsulation) چیست؟

  • محدود کردن دسترسی مستقیم به داده‌های داخلی یک شیء
  • هدف: جلوگیری از تغییر ناخواسته/نادرست داده‌ها از بیرون کلاس

سطوح دسترسی در پایتون (بر پایه قرارداد، نه اجبار سخت)

نوع نوشتار معنی
Public self.name از همه‌جا در دسترسه
Protected self._name (یک آندرلاین) قرارداده که فقط داخل کلاس/فرزندان استفاده بشه (اجباری نیست)
Private self.__name (دو آندرلاین) با name mangling محافظت می‌شه، دسترسی مستقیم بیرون سخت‌تره
class Account:
    def __init__(self, balance):
        self.__balance = balance   # private

    def get_balance(self):
        return self.__balance

acc = Account(1000)
print(acc.get_balance())    # 1000
print(acc.__balance)        # خطا: AttributeError

نکته کلاسی: پایتون واقعاً private نداره — __balance در پشت صحنه به _Account__balance تبدیل می‌شه (Name Mangling)؛ یعنی هنوز قابل دسترسیه ولی سخت‌تر و دلسردکننده‌ست.

دسترسی کنترل‌شده با property

  • روش استاندارد پایتون برای getter/setter، به‌جای متدهای دستی
class Account:
    def __init__(self, balance):
        self.__balance = balance

    @property
    def balance(self):          # getter
        return self.__balance

    @balance.setter
    def balance(self, value):   # setter
        if value < 0:
            raise ValueError("موجودی نمی‌تونه منفی باشه")
        self.__balance = value

acc = Account(1000)
print(acc.balance)      # مثل یک attribute استفاده می‌شه، نه متد
acc.balance = 2000       # از setter عبور می‌کنه و اعتبارسنجی می‌شه
  • مزیت: می‌تونیم منطق اعتبارسنجی رو بدون تغییر نحوه استفاده بیرون از کلاس، اضافه کنیم

انتزاع (Abstraction) چیست؟

  • مخفی کردن جزئیات پیاده‌سازی و نمایش فقط رابط (Interface) ضروری به کاربر کلاس
  • تمرکز روی “چه کاری انجام می‌شه” نه “چطور انجام می‌شه”

پیاده‌سازی انتزاع با abc (Abstract Base Class)

from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self):
        pass

class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius

    def area(self):
        return 3.14 * self.radius ** 2

c = Circle(5)
print(c.area())
78.5
  • Shape یک کلاس انتزاعیه — نمی‌شه مستقیم ازش شیء ساخت
s = Shape()   # خطا: TypeError: Can't instantiate abstract class
  • هر کلاس فرزند مجبوره متد area() رو پیاده‌سازی کنه، وگرنه خودش هم انتزاعی می‌مونه

جمع‌بندی تفاوت کپسوله‌سازی و انتزاع

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