OOP في Python: البرمجة الكائنية بأمثلة عملية
لغات البرمجة

OOP في Python: البرمجة الكائنية بأمثلة عملية

البرمجة الكائنية تنظّم كودك وتسهّل صيانته. تعلّم الكلاسات، الوراثة، والتغليف في Python.

م
مؤسس LahbabiGuide
4 دقائق قراءة
شارك:

لماذا OOP؟

البرمجة الكائنية (Object-Oriented Programming) تنظّم الكود في كائنات تحوي بيانات ودوال. بدلاً من وظائف متفرقة، تصمّم "أشياء" في عالمك.

الفوائد:

  • تنظيم: الكود منطقي ومفهوم
  • إعادة استخدام: الوراثة تُقلّل التكرار
  • صيانة: تغيير في مكان واحد يؤثّر في الكل
  • تقسيم المسؤوليات: كل كلاس يعرف شيئاً واحداً

أول كلاس

python
class User:
    # constructor — يُنفَّذ عند الإنشاء
    def __init__(self, name, email):
        self.name = name
        self.email = email

    # method
    def greet(self):
        return f"مرحبا {self.name}"

# إنشاء كائنات
ahmad = User("أحمد", "[email protected]")
sara = User("سارة", "[email protected]")

print(ahmad.greet())    # مرحبا أحمد
print(sara.email)       # [email protected]

self يشير إلى الكائن نفسه — يجب أن تكون أول parameter في أي method.

الـ Attributes

Instance attributes — لكل كائن

python
class Car:
    def __init__(self, brand, color):
        self.brand = brand
        self.color = color

car1 = Car("Toyota", "أبيض")
car2 = Car("Honda", "أحمر")

print(car1.brand)  # Toyota
print(car2.brand)  # Honda

Class attributes — مشتركة

python
class Car:
    wheels = 4  # كل السيارات لها 4 عجلات

    def __init__(self, brand):
        self.brand = brand

car = Car("Mazda")
print(car.wheels)    # 4
print(Car.wheels)    # 4
إعلان

Methods

Instance methods (عادية)

python
class BankAccount:
    def __init__(self, balance=0):
        self.balance = balance

    def deposit(self, amount):
        self.balance += amount
        return self.balance

    def withdraw(self, amount):
        if amount > self.balance:
            raise ValueError("رصيد غير كافٍ")
        self.balance -= amount
        return self.balance

account = BankAccount(100)
account.deposit(50)      # 150
account.withdraw(30)     # 120

Class methods و static methods

python
class Temperature:
    def __init__(self, celsius):
        self.celsius = celsius

    @classmethod
    def from_fahrenheit(cls, f):
        # cls = الكلاس نفسه — يُنشئ instance جديدة
        return cls((f - 32) * 5/9)

    @staticmethod
    def is_freezing(c):
        # لا يحتاج self ولا cls — دالة مساعدة في الكلاس
        return c <= 0

temp = Temperature.from_fahrenheit(100)
print(temp.celsius)                      # 37.78
print(Temperature.is_freezing(-5))       # True

الوراثة (Inheritance)

كلاس يرث من كلاس آخر:

python
class Animal:
    def __init__(self, name):
        self.name = name

    def eat(self):
        return f"{self.name} يأكل"

class Dog(Animal):
    def __init__(self, name, breed):
        super().__init__(name)  # استدعِ constructor الأب
        self.breed = breed

    def bark(self):
        return f"{self.name} ينبح: هوه هوه!"

dog = Dog("ركس", "Husky")
print(dog.eat())    # ركس يأكل (من Animal)
print(dog.bark())   # ركس ينبح (من Dog)
print(dog.breed)    # Husky

Method Overriding

python
class Animal:
    def speak(self):
        return "..."

class Cat(Animal):
    def speak(self):  # يُعيد تعريف method الأب
        return "مياو"

class Dog(Animal):
    def speak(self):
        return "هوه"

animals = [Cat(), Dog(), Animal()]
for a in animals:
    print(a.speak())
# مياو / هوه / ...

التغليف (Encapsulation)

إخفاء التفاصيل الداخلية:

python
class BankAccount:
    def __init__(self, balance):
        self._balance = balance   # _ يشير أنه خاص (اتّفاقاً)

    @property
    def balance(self):
        """قراءة فقط"""
        return self._balance

    @balance.setter
    def balance(self, value):
        """التحقّق عند التعديل"""
        if value < 0:
            raise ValueError("الرصيد لا يمكن أن يكون سالباً")
        self._balance = value

account = BankAccount(100)
print(account.balance)     # 100 (يستخدم getter)
account.balance = 200      # يستخدم setter
account.balance = -50      # ValueError

Polymorphism (تعدّد الأشكال)

نفس الاستدعاء، سلوك مختلف حسب النوع:

python
class Shape:
    def area(self):
        raise NotImplementedError

class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius
    def area(self):
        return 3.14 * self.radius ** 2

class Rectangle(Shape):
    def __init__(self, w, h):
        self.w, self.h = w, h
    def area(self):
        return self.w * self.h

shapes = [Circle(5), Rectangle(3, 4)]
for s in shapes:
    print(s.area())    # 78.5 / 12

Dunder methods (السحرية)

تتحكّم بسلوك الكائن:

python
class Book:
    def __init__(self, title, pages):
        self.title = title
        self.pages = pages

    def __repr__(self):
        return f"Book({self.title!r})"

    def __str__(self):
        return f"كتاب: {self.title}"

    def __len__(self):
        return self.pages

    def __eq__(self, other):
        return isinstance(other, Book) and self.title == other.title

book = Book("الأسس", 250)
print(book)              # كتاب: الأسس (يستخدم __str__)
print(repr(book))        # Book('الأسس')
print(len(book))         # 250
print(book == Book("الأسس", 300))  # True

Dataclasses — اختصار قوي

python
from dataclasses import dataclass

@dataclass
class User:
    name: str
    email: str
    age: int = 0

user = User("سارة", "[email protected]", 25)
print(user)  # User(name='سارة', email='[email protected]', age=25)

بدلاً من كتابة init و repr يدوياً.

مثال كامل: نظام صغير

python
from datetime import datetime

class Post:
    def __init__(self, title, author):
        self.title = title
        self.author = author
        self.created_at = datetime.now()
        self.likes = 0

    def like(self):
        self.likes += 1

    def __str__(self):
        return f"{self.title} بقلم {self.author.name}"

class Author:
    def __init__(self, name):
        self.name = name
        self.posts = []

    def publish(self, title):
        post = Post(title, self)
        self.posts.append(post)
        return post

    def total_likes(self):
        return sum(p.likes for p in self.posts)

# الاستخدام
author = Author("محمد")
post1 = author.publish("مقدمة Python")
post2 = author.publish("OOP سهلاً")
post1.like()
post1.like()

print(post1)                     # مقدمة Python بقلم محمد
print(author.total_likes())      # 2

الأخطاء الشائعة

  • نسيان self في method
  • تعديل class attribute عرضاً بدل instance attribute
  • الوراثة العميقة (Dog → Mammal → Animal → LivingBeing) — صعبة الصيانة
  • كلاسات ضخمة تفعل كل شيء — قسّمها

الأسئلة الشائعة

متى أستخدم OOP؟

للمشاريع بحاجة تنظيم — إدارة مستخدمين، ألعاب، نمذجة بيانات. للـ scripts البسيطة، الدوال تكفي.

Abstract classes؟

Python يدعمها عبر abc:

python
from abc import ABC, abstractmethod
class Shape(ABC):
    @abstractmethod
    def area(self): pass

OOP vs Functional؟

الاثنان مفيدان. OOP للدولة المتغيّرة، Functional للتحويلات النقية. Python يدعم الاثنين.

شارك:
المزيد من لغات البرمجة
اقرأ أيضاً

مقالات ذات صلة