مقدمة
من أكثر المفاهيم التي تسبب ارتباكًا للمبتدئين في Python مفهوم OOP أو Object-Oriented Programming.
السبب غالبًا ليس صعوبة كتابة الكود، وإنما اختلاف طريقة التفكير. في البداية نتعامل مع البرنامج على أنه مجموعة أوامر ودوال، ثم نبدأ في التفكير في البرنامج على شكل كائنات لها بيانات وسلوكيات.
ولأن Django والعديد من المكتبات الحديثة تعتمد بشكل كبير على الكائنات والكلاسات، فإن فهم OOP بشكل جيد سيجعل طريقك كمطور Backend أسهل بكثير.
أولًا: ما معنى OOP في الحياة اليومية؟
تخيل أنك تعمل على نظام بنكي. لديك حسابات للعملاء.
كل حساب يمتلك بيانات مثل:
- اسم صاحب الحساب.
- رقم الحساب.
- الرصيد.
ويمتلك أيضًا سلوكيات مثل:
- إيداع مبلغ.
- سحب مبلغ.
- معرفة الرصيد.
هنا يمكننا تمثيل الحساب في البرنامج باستخدام Class.
1. ما هو الـ Class؟
الـ Class يمكن اعتباره قالبًا أو مخططًا نستخدمه لإنشاء Objects متشابهة.
مثلًا يمكننا إنشاء Class اسمه
BankAccount.
class BankAccount:
def __init__(self, owner, balance):
self.owner = owner
self.balance = balance
def deposit(self, amount):
self.balance += amount
def get_balance(self):
return self.balance
هنا قمنا بتعريف قالب لحساب بنكي. لكنه ما زال مجرد Class، ولم ننشئ حسابًا فعليًا بعد.
2. ما هو الـ Object؟
الـ Object هو نسخة فعلية يتم إنشاؤها من الـ Class.
يمكن أن يكون لدينا Class واحد، ولكن ننشئ منه عددًا كبيرًا من Objects.
account1 = BankAccount(
"محمد",
1000
)
account2 = BankAccount(
"علي",
500
)
هنا أصبح لدينا حسابان مستقلان، وكل واحد منهما يمتلك بياناته الخاصة.
print(account1.owner)
print(account1.balance)
print(account2.owner)
print(account2.balance)
الـ Class هو القالب، والـ Object هو الشيء الذي أنشأناه من ذلك القالب.
3. ما معنى self؟
كلمة self تشير إلى
الـ Object الحالي الذي يتم تنفيذ
الميثود عليه.
class User:
def __init__(self, name):
self.name = name
def say_hello(self):
print(f"مرحبًا، أنا {self.name}")
عندما نكتب:
user = User("محمد")
user.say_hello()
فإن self داخل
say_hello() يشير إلى
الكائن user.
4. ما وظيفة __init__؟
الدالة __init__ تستخدم
لتهيئة Object عند إنشائه.
class User:
def __init__(self, name, email):
self.name = name
self.email = email
user = User(
"محمد",
"mohammed@example.com"
)
بمجرد إنشاء الـ Object يتم تنفيذ
__init__ لتهيئة
البيانات المطلوبة.
5. Encapsulation — التغليف
التغليف يعني تنظيم البيانات والسلوكيات داخل الكائن والتحكم في كيفية الوصول إليها أو تعديلها.
مثال: لا نريد أن يستطيع أي جزء من البرنامج تعديل رصيد الحساب بطريقة عشوائية.
class BankAccount:
def __init__(self, balance):
self._balance = balance
def deposit(self, amount):
if amount > 0:
self._balance += amount
def get_balance(self):
return self._balance
بدلًا من تعديل الرصيد مباشرة، نستخدم ميثود مخصصة للتحكم في عملية الإيداع.
استخدام الشرطة السفلية مثل
_balance يمثل
اصطلاحًا يدل على أن المتغير
مخصص للاستخدام الداخلي، وليس
نظام صلاحيات صارمًا مثل بعض
اللغات الأخرى.
6. Inheritance — الوراثة
الوراثة تسمح لـ Class جديد بالاستفادة من خصائص وسلوكيات Class موجود مسبقًا.
تخيل أن لدينا Class عام اسمه
User، وبعد ذلك نريد
إنشاء Admin.
class User:
def __init__(self, name):
self.name = name
def login(self):
print("User logged in")
class Admin(User):
def delete_user(self):
print("User deleted")
الآن Admin يستطيع
استخدام الميثود الموجودة في
User بالإضافة إلى
الميثود الخاصة به.
admin = Admin("محمد")
admin.login()
admin.delete_user()
7. Abstraction — التجريد
التجريد يعني إخفاء التفاصيل الداخلية المعقدة والتركيز على الواجهة التي يحتاج المستخدم أو باقي النظام إلى التعامل معها.
مثال من الحياة اليومية: عندما تستخدم السيارة، أنت لا تحتاج إلى معرفة كل التفاصيل الداخلية للمحرك حتى تستخدم دواسة الوقود.
في Python يمكن استخدام
abc لبناء
Abstract Classes.
from abc import ABC, abstractmethod
class Payment(ABC):
@abstractmethod
def pay(self, amount):
pass
class CreditCardPayment(Payment):
def pay(self, amount):
print(f"Paid {amount} using credit card")
الـ Class الأساسي يحدد أن عملية الدفع يجب أن تكون موجودة، بينما الـ Class المتخصص يحدد كيفية تنفيذها.
8. Polymorphism — تعدد الأشكال
المقصود بتعدد الأشكال أن نتعامل مع Objects مختلفة من خلال واجهة أو سلوك مشترك، بينما يمكن لكل Object تنفيذ السلوك بطريقته الخاصة.
class Dog:
def speak(self):
return "Woof"
class Cat:
def speak(self):
return "Meow"
animals = [
Dog(),
Cat()
]
for animal in animals:
print(animal.speak())
كلا الكائنين يمتلكان ميثود باسم
speak()، لكن النتيجة
تختلف حسب نوع الكائن.
9. أنواع Methods المهمة
في Python ستتعامل مع أكثر من نوع من الميثود داخل Classes.
Instance Method
class User:
def say_hello(self):
return "Hello"
Class Method
class User:
total_users = 0
@classmethod
def get_total_users(cls):
return cls.total_users
Static Method
class MathHelper:
@staticmethod
def add(a, b):
return a + b
لا تحتاج إلى حفظ هذه الأنواع بشكل منفصل فقط؛ الأهم أن تفهم متى يكون استخدام كل نوع مناسبًا.
10. لماذا OOP مهمة لمطور Backend؟
هنا تبدأ أهمية OOP بالنسبة لك كمطور Python Backend.
في المشاريع الحقيقية لن تعمل فقط مع ملفات صغيرة تحتوي على دوال. ستتعامل مع Models و Services و Classes ومكونات كثيرة تتفاعل مع بعضها.
Django نفسه يعتمد بشكل كبير على مفهوم Classes و Objects.
على سبيل المثال، عندما تعرف Model في Django فأنت تتعامل مع Class يمثل بيانات معينة داخل النظام.
class Product:
def __init__(self, name, price):
self.name = name
self.price = price
def get_price(self):
return self.price
لذلك فإن فهم OOP جيدًا يجعلك قادرًا على فهم Frameworks والمكتبات الحديثة بدل التعامل معها بطريقة تعتمد على الحفظ فقط.
11. لا تستخدم OOP لمجرد استخدامها
من الأخطاء الشائعة أن يعتقد المطور أن كل مشكلة يجب حلها باستخدام Class.
OOP أداة، وليست هدفًا بحد ذاتها. أحيانًا تكون الدالة البسيطة هي الحل الأفضل.
استخدم الـ Class عندما يكون لديك كائن يمتلك بيانات وسلوكًا مرتبطًا به، أو عندما يساعدك التصميم الكائني على جعل المشروع أوضح وأسهل في الصيانة.
أخطاء شائعة عند تعلم OOP
- حفظ تعريف Class و Object دون فهم العلاقة بينهما.
- استخدام الوراثة في كل مكان.
- الخلط بين Class و Object.
- عدم فهم وظيفة self.
- اعتبار underscore نظام حماية كامل للبيانات.
- إنشاء Classes معقدة دون حاجة.
- تعلم المفاهيم نظريًا دون بناء مشروع عملي.
تمرين عملي
حتى تتأكد أنك فهمت OOP، حاول بناء نظام بسيط لإدارة المنتجات.
أنشئ Class باسم
Product يحتوي على:
- اسم المنتج.
- السعر.
- الكمية.
- Method لحساب القيمة الإجمالية.
- Method لتحديث الكمية.
بعد ذلك أنشئ عدة Objects واختبر العمليات عليها.
حاول إضافة Class آخر اسمه
DigitalProduct
يرث من Product
ويضيف خاصية خاصة بالمنتج الرقمي.
الخلاصة
OOP ليست مجموعة مصطلحات يجب حفظها، وإنما طريقة لتنظيم التفكير والكود.
ابدأ بفهم العلاقة بين
Class و Object،
ثم تعلم Attributes و Methods و
self و
__init__.
بعد ذلك انتقل إلى المفاهيم الأعمق: Encapsulation و Inheritance و Abstraction و Polymorphism.
ومع بناء مشاريع Python حقيقية ستبدأ هذه المفاهيم بالارتباط ببعضها بشكل طبيعي، وستصبح قراءة كود Django أسهل بكثير.
بعد فهم OOP، انتقل إلى Modules و Packages و Exception Handling ثم ابدأ في بناء مشاريع صغيرة باستخدام Python قبل الانتقال إلى Django.