١. لماذا برمجة الكائنات؟
تخيل أنك تبني نظام مدرسة. عندك 200 طالب، كل طالب له اسم وعمر ودرجات. بدون OOP ستكتب 200 مجموعة من المتغيرات. مع OOP تصنع قالباً واحداً (Class) وتنشئ منه 200 طالب في ثواني.
Class (الكلاس)
القالب أو المخطط — يصف كيف يبدو الشيء
Object (الكائن)
نسخة حقيقية من الكلاس بقيم فعلية
Attribute (الخاصية)
بيانات الكائن — مثل الاسم والعمر
Method (الدالة)
ما يستطيع الكائن فعله — مثل الدراسة
القالب
BMW 2023
Toyota 2022
Honda 2024
٢. إنشاء أول كلاس
# تعريف الكلاس
class Car:
# خاصية مشتركة بين كل الكائنات
wheels = 4
def honk(self):
print("بيب بيب! 📯")
# إنشاء كائنات من الكلاس
car1 = Car()
car2 = Car()
car1.honk() # بيب بيب!
print(car1.wheels) # 4
print(type(car1)) # <class 'Car'>
print(isinstance(car1, Car)) # True
self هو إشارة إلى الكائن الحالي. عندما تكتب car1.honk() بايثون يمرر car1 تلقائياً كـ self. دائماً اجعله أول معامل في دوال الكلاس.٣. دالة __init__ — منشئ الكائن
دالة __init__ تُستدعى تلقائياً عند إنشاء كائن جديد. تستخدمها لتحديد البيانات الأولية للكائن.
class Student:
def __init__(self, name, age, city):
self.name = name
self.age = age
self.city = city
self.grades = [] # قائمة فارغة لكل طالب
def introduce(self):
print(f"اسمي {self.name}، عمري {self.age} من {self.city}")
def add_grade(self, grade):
self.grades.append(grade)
def get_average(self):
if not self.grades:
return 0
return sum(self.grades) / len(self.grades)
# إنشاء طلاب
s1 = Student("خليل", 14, "مراكش")
s2 = Student("فاطمة", 15, "الرباط")
s1.introduce()
s1.add_grade(18)
s1.add_grade(16)
print(f"معدل {s1.name}: {s1.get_average()}") # 17.0
٤. الدوال الخاصة (Dunder Methods)
بايثون لديه دوال مدمجة خاصة بين شرطتين مزدوجتين. أشهرها __str__ لطباعة الكائن بشكل جميل.
class Book:
def __init__(self, title, author, pages):
self.title = title
self.author = author
self.pages = pages
def __str__(self):
# يُستخدم عند print()
return f"📖 '{self.title}' بقلم {self.author} ({self.pages} صفحة)"
def __len__(self):
# يُستخدم مع len()
return self.pages
def __eq__(self, other):
# يُستخدم مع ==
return self.title == other.title
b1 = Book("ألف ليلة وليلة", "مجهول", 1000)
b2 = Book("المقدمة", "ابن خلدون", 800)
print(b1) # 📖 'ألف ليلة وليلة' بقلم مجهول (1000 صفحة)
print(len(b1)) # 1000
print(b1 == b2) # False
٥. الوراثة (Inheritance)
الوراثة تسمح لكلاس أن يأخذ كل خصائص ودوال كلاس آخر ويضيف عليها. مثل الإرث الحقيقي!
name, age, introduce()
grades, study()
subject, teach()
# الكلاس الأب (Parent)
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def introduce(self):
print(f"مرحباً، اسمي {self.name} وعمري {self.age}")
# الكلاس الابن (Child) يرث من Person
class Student(Person):
def __init__(self, name, age, school):
super().__init__(name, age) # استدعاء init الأب
self.school = school
self.grades = []
def study(self, subject):
print(f"{self.name} يدرس {subject} 📚")
class Teacher(Person):
def __init__(self, name, age, subject):
super().__init__(name, age)
self.subject = subject
def teach(self):
print(f"الأستاذ {self.name} يدرّس {self.subject} 👨🏫")
# استخدام
student = Student("خليل", 14, "ثانوية مراكش")
teacher = Teacher("الأستاذ محمد", 40, "الرياضيات")
student.introduce() # موروثة من Person
student.study("بايثون")
teacher.introduce()
teacher.teach()
٦. super() — التواصل مع الأب
super() تتيح لك استدعاء دوال الكلاس الأب. مفيد جداً لإضافة سلوك على ما موجود بدل إعادة كتابته.
class Animal:
def __init__(self, name):
self.name = name
print(f"🐾 تم إنشاء حيوان: {name}")
def eat(self):
print(f"{self.name} يأكل 🍖")
class Dog(Animal):
def __init__(self, name, breed):
super().__init__(name) # init الأب
self.breed = breed
def bark(self):
print(f"{self.name} ينبح: هاو هاو! 🐕")
def eat(self):
super().eat() # سلوك الأب أولاً
print(" ثم يهز ذيله 🐾") # ثم نضيف سلوكاً جديداً
rex = Dog("ريكس", "Labrador")
rex.bark()
rex.eat()
٧. تعدد الأشكال (Polymorphism)
نفس اسم الدالة يتصرف بشكل مختلف حسب الكائن. كلهم يعرفون "يتكلمون" لكن كل واحد بطريقته.
class Animal:
def speak(self):
return "صوت..."
class Dog(Animal):
def speak(self):
return "هاو هاو! 🐕"
class Cat(Animal):
def speak(self):
return "مياو! 🐱"
class Cow(Animal):
def speak(self):
return "خوار! 🐄"
# نفس الدالة، نتائج مختلفة
animals = [Dog(), Cat(), Cow(), Dog()]
for animal in animals:
print(f"{type(animal).__name__}: {animal.speak()}")
٨. التغليف (Encapsulation)
التغليف يخفي البيانات الداخلية ويمنع تعديلها مباشرة. تستخدم _ أو __ قبل اسم الخاصية.
class BankAccount:
def __init__(self, owner, balance=0):
self.owner = owner
self.__balance = balance # خاص — __ يمنع الوصول المباشر
def deposit(self, amount):
if amount > 0:
self.__balance += amount
print(f"✅ تم إيداع {amount} درهم")
def withdraw(self, amount):
if amount > self.__balance:
print("❌ رصيدك غير كافٍ!")
else:
self.__balance -= amount
print(f"💸 تم سحب {amount} درهم")
def get_balance(self):
return f"💰 رصيد {self.owner}: {self.__balance} درهم"
acc = BankAccount("خليل", 500)
acc.deposit(200)
acc.withdraw(100)
print(acc.get_balance()) # 600 درهم
# print(acc.__balance) ← خطأ! لا يمكن الوصول
__ للبيانات الحساسة (كلمات مرور، أرصدة) التي لا يجب أن يعدلها أحد مباشرة.🚀 المشروع — نظام إدارة مكتبة
طبّق OOP في مشروع حقيقي يجمع كل المفاهيم: كلاس الكتاب، كلاس المكتبة، الاستعارة والإرجاع.
# ============================
# 📚 نظام إدارة مكتبة
# ============================
class Book:
def __init__(self, title, author, year):
self.title = title
self.author = author
self.year = year
self.is_borrowed = False
def __str__(self):
status = "❌ مستعار" if self.is_borrowed else "✅ متاح"
return f"📖 {self.title} ({self.author}, {self.year}) — {status}"
class Library:
def __init__(self, name):
self.name = name
self.books = []
def add_book(self, book):
self.books.append(book)
print(f"✅ أُضيف: {book.title}")
def show_all(self):
print(f"\n📚 مكتبة {self.name} — {len(self.books)} كتاب:")
for i, b in enumerate(self.books, 1):
print(f" {i}. {b}")
def borrow(self, title, person):
for book in self.books:
if book.title == title:
if book.is_borrowed:
print(f"❌ '{title}' مستعار حالياً")
else:
book.is_borrowed = True
print(f"📗 {person} استعار '{title}'")
return
print(f"❓ الكتاب '{title}' غير موجود")
def return_book(self, title):
for book in self.books:
if book.title == title:
book.is_borrowed = False
print(f"✅ تم إرجاع '{title}'")
return
# ---- اختبار النظام ----
lib = Library("مكتبة مراكش")
lib.add_book(Book("ألف ليلة وليلة", "مجهول", 800))
lib.add_book(Book("المقدمة", "ابن خلدون", 1377))
lib.add_book(Book("كليلة ودمنة", "ابن المقفع", 750))
lib.show_all()
lib.borrow("المقدمة", "خليل")
lib.borrow("المقدمة", "أحمد") # مستعار
lib.return_book("المقدمة")
lib.show_all()
🎉 أتقنت برمجة الكائنات!
الآن تعرف الكلاسات، __init__، الوراثة، super()، تعدد الأشكال، والتغليف.
الدرس التالي: تحليل البيانات ببايثون — ستتعلم pandas وmatplotlib.
الدرس التالي: تحليل البيانات ←