C++: أساسيات الوراثة
آخر تحديث: 2026-08-26
تخيّل أنك كتبت فئتَي
StudentوTeacher، واكتشفت أن كليهما يمتلك اسماً وعمراً، لكن الطلاب لديهم أرقام طلابية والمعلمون لديهم أرقام وظيفية.هل يمكنك إعادة استخدام كود فئة
Person؟ الوراثة تفعل ذلك بالضبط — إنشاء علاقة "أب-ابن" بين الفئات.
1. ما هي الوراثة؟
(1) 1.1 الوراثة في الحياة اليومية
| مثال من الحياة اليومية | المكافئ البرمجي |
|---|---|
| يرث الطفل صفات من والديه (لون العينين، الطول، إلخ) | الفئة المشتقة ترث أعضاء من فئتها الأساسية |
| يمكن للطفل أن يمتلك صفاته الخاصة (مثل المواهب الخاصة) | الفئة المشتقة يمكنها إضافة أعضاء جدد |
جوهر الوراثة: إنشاء فئات جديدة عبر توسيع فئات موجودة.
(2) 1.2 لماذا نحتاج الوراثة؟
بدون الوراثة (كود مكرر):
▶ مثال 2: مثال برمجي (الصعوبة ⭐)
#include <iostream>
#include <string>
// فئة الطالب
class Student {
std::string name;
int age;
std::string studentId;
};
// فئة المعلم
class Teacher {
std::string name; // ❌ مكرر
int age; // ❌ مكرر
std::string teacherId;
};
الخرج:
(program output)
مع الوراثة (إعادة استخدام الكود):
#include <iostream>
#include <string>
// الفئة الأساسية (الفئة الأب)
class Person {
public:
std::string name;
int age;
};
// الفئة المشتقة (الفئة الابن)
class Student : public Person {
public:
std::string studentId; // عضو جديد
};
class Teacher : public Person {
public:
std::string teacherId; // عضو جديد
};
2. الصياغة الأساسية للوراثة
(1) 2.1 الإعلان عن فئة مشتقة
الصياغة:
class DerivedClassName : inheritanceMode BaseClassName {
// أعضاء جدد
};
مثال:
#include <iostream>
#include <string>
class Person {
public:
std::string name;
int age;
};
// Student ترث من Person
class Student : public Person {
public:
std::string studentId;
};
int main() {
Student s1;
s1.name = "Alice"; // ✅ ورث name
s1.age = 20; // ✅ ورث age
s1.studentId = "2024001"; // عضو خاص
std::cout << "Name: " << s1.name << std::endl;
std::cout << "Age: " << s1.age << std::endl;
std::cout << "Student ID: " << s1.studentId << std::endl;
return 0;
}
3. أنماط الوراثة (التحكم في الوصول)
(1) 3.1 أنماط الوراثة الثلاثة
| عضو الفئة الأساسية \ نمط الوراثة | الوراثة public | الوراثة protected | الوراثة private |
|---|---|---|---|
| أعضاء public | public (بدون تغيير) | protected | private |
| أعضاء protected | protected | protected | private |
| أعضاء private | غير قابل للوصول | غير قابل للوصول | غير قابل للوصول |
💡 نقطة مهمة: النمط الأكثر استخداماً هو الوراثة public.
(2) 3.2 الوراثة public (موصى بها)
#include <iostream>
#include <string>
class Person {
private:
std::string id; // عضو خاص: غير قابل للوصول من الفئة المشتقة
protected:
std::string address; // عضو محمي: قابل للوصول من الفئة المشتقة
public:
std::string name; // عضو عام: قابل للوصول من الجميع
void introduce() {
std::cout << "My name is " << name << std::endl;
}
};
class Student : public Person {
public:
void setAddress(const std::string& addr) {
address = addr; // ✅ يمكن الوصول إلى العضو المحمي
// id = "123"; // ❌ لا يمكن الوصول إلى العضو الخاص
}
};
int main() {
Student s1;
s1.name = "Alice"; // ✅ قابل للوصول
// s1.address = "Wuhan"; // ❌ غير قابل للوصول (محمي)
return 0;
}
4. البانيات والوراثة
(1) 4.1 ترتيب استدعاء باني الفئة المشتقة
القاعدة: يُستدعى باني الفئة الأساسية أولاً، ثم باني الفئة المشتقة.
#include <iostream>
#include <string>
class Person {
public:
Person() {
std::cout << "Person constructor" << std::endl;
}
};
class Student : public Person {
public:
Student() {
std::cout << "Student constructor" << std::endl;
}
};
int main() {
Student s1;
return 0;
}
💡 نقطة مهمة: ترتيب استدعاء المدمرات معكوس — يُستدعى مدمر الفئة المشتقة أولاً، ثم مدمر الفئة الأساسية.
5. تطبيق: نظام إدارة طلاب بسيط (نسخة الوراثة)
▶ مثال 1: تطبيق باستخدام الوراثة (الصعوبة ⭐⭐)
#include <iostream>
#include <string>
// الفئة الأساسية
class Person {
protected:
std::string name;
int age;
public:
Person(const std::string& n, int a) : name(n), age(a) {}
void introduce() {
std::cout << "Name: " << name << ",Age: " << age << std::endl;
}
};
// الفئة المشتقة: Student
class Student : public Person {
private:
std::string studentId;
double score;
public:
Student(const std::string& n, int a, const std::string& id, double s)
: Person(n, a), studentId(id), score(s) {}
void introduce() {
Person::introduce(); // استدعاء introduce من الفئة الأساسية
std::cout << "Student ID: " << studentId << ",Score: " << score << std::endl;
}
};
int main() {
Student s1("Alice", 20, "2024001", 92.5);
s1.introduce();
return 0;
}
الخرج:
Name: Alice,Age: 20
Student ID: 2024001,Score: 92.5
❓ أسئلة شائعة
public: الأكثر استخداماً، تحافظ على واجهة الفئة الأساسية > - الوراثة protected: نادراً ما تُستخدم > - الوراثة private: نادراً ما تُستخدم▶ مثال 3: باني فئة مشتقة (الصعوبة ⭐)
#include <iostream>
#include <string>
class Animal {
protected:
std::string name;
public:
Animal(std::string n) : name(n) {}
void speak() { std::cout << name << "makes a sound" << std::endl; }
};
class Dog : public Animal {
public:
Dog(std::string n) : Animal(n) {}
void speak() { std::cout << name << "barks" << std::endl; }
};
int main() {
Dog dog("Wangcai");
dog.speak();
return 0;
}
الخرج:
Wangcaibarks
📖 ملخص
- الوراثة تتيح للفئات المشتقة إعادة استخدام كود الفئة الأساسية
- الوراثة public هي الأكثر استخداماً
- الفئات المشتقة لا يمكنها الوصول إلى الأعضاء
privateفي الفئة الأساسية - الفئات المشتقة يمكنها الوصول إلى الأعضاء
protectedفي الفئة الأساسية - ترتيب استدعاء البانيات: الفئة الأساسية ← الفئة المشتقة
📝 تمارين
-
أساسي (الصعوبة ⭐): عرّف فئة أساسية
Animalبعضوname. اجعل فئتيDogوCatترثان منها. -
متوسط (الصعوبة ⭐⭐): وسّع البرنامج أعلاه بإضافة دالة افتراضية
void speak()إلىAnimal(ستتعلم عن الدوال الافتراضية لاحقاً)، واجعلDogوCatتتجاوزانها. -
متقدم (الصعوبة ⭐⭐⭐): صمم هرمية فئات نظام إدارة مكتبة:
-
Person(الاسم، العمر) -
Studentيرث منPerson(رقم الطالب، عدد الكتب المستعارة) -
Teacherيرث منPerson(الرقم الوظيفي، عدد الكتب المستعارة) -
نفّذ وظائف الاستعارة والإرجاع.
-
الوراثة: الفئات المشتقة تمتلك جميع أعضاء الفئة الأساسية
- الوراثة public/protected/private تتحكم في صلاحيات الوصول
- بانيات الفئات المشتقة تستدعي بانيات الفئات الأساسية
- علاقة is-a: الفئة المشتقة هي نوع من الفئة الأساسية
- الوراثة الماسية تتطلب وراثة افتراضية لحل الغموض
6. 🚀 الخطوات التالية
الآن بعد أن تعلمت أساسيات الوراثة، لننتقل إلى تعدد الأشكال (الدرس 32) — السماح لمؤشرات الفئة الأساسية باستدعاء دوال الفئة المشتقة لتحقيق "واجهة واحدة، تطبيقات متعددة"!