الوراثة الأساسية
جزء من قسم Object Oriented Programming في رحلة PHP على Coddy — الدرس 21 من 91.
تسمح الوراثة لـ class باكتساب الخصائص والأساليب من class آخر. فبدلاً من إعادة كتابة الكود نفسه، يمكنك إنشاء base class بوظائف مشتركة وجعل classes أخرى ترث منها.
تُسمى الفئة التي يتم التوريث منها الفئة الأب (أو الفئة الأساسية)، وتُسمى الفئة التي تَرِث الفئة الابن. تستخدم الكلمة المفتاحية extends لإنشاء هذه العلاقة:
<?php
class Animal {
public $name;
public function __construct($name) {
this->name = $name;
}
public function speak() {
return "$this->name makes a sound";
}
}
class Dog extends Animal {
public function fetch() {
return "$this->name fetches the ball";
}
}
$dog = new Dog("Buddy");
echo $dog->speak() . "\n";
echo $dog->fetch();
المخرجات:
Buddy makes a sound
Buddy fetches the ballتمتلك فئة Dog تلقائيًا حق الوصول إلى خاصية $name، والمنشئ، ودالة speak() من Animal. كما أنها تُعرف دالة fetch() الخاصة بها والتي تمتلكها الكلاب فقط.
هذا ينشئ تسلسلاً هرمياً واضحاً: كل كلب هو حيوان، لذا فمن المنطقي أن يرث Dog من Animal. يمكن للفئة الابنة استخدام كل شيء من الفئة الأب مع إضافة سلوكها الخاص المتخصص.
نقطة رئيسية: تعزز الوراثة (Inheritance) إعادة استخدام الكود وتنشئ علاقات منطقية بين الفئات (classes). ترث الفئة التابعة (child class) جميع الأعضاء العامة (public) والمحمية (protected) من الفئة الأساسية (parent)، مما يقلل من التكرار ويجعل الكود الخاص بك أسهل في الصيانة.
التحدي
سهلدعونا نبني نظام تسلسل هرمي للمركبات يوضح كيف يسمح التوريث للفئات الفرعية (child classes) بمشاركة الوظائف من الفئة الأب (parent class) مع إضافة سلوكياتها المتخصصة.
ستقوم بتنظيم الكود الخاص بك عبر ثلاثة ملفات:
Vehicle.php— قم بتعريف فئةVehicleالتي تعمل كأب لجميع المركبات. يجب أن تحتوي على خاصية عامة$brandومنشئ (constructor) يقبل العلامة التجارية ويقوم بتعيينها. قم بتضمين تابعstart()يعيد"[brand] is starting"وتابعstop()يعيد"[brand] is stopping".Motorcycle.php— قم بتعريف فئةMotorcycleالتي ترث منVehicle. قم بتضمين ملف Vehicle في الأعلى. لا تحتاج فئة Motorcycle إلى منشئ خاص بها لأنها سترث منشئ الفئة الأب. أضف تابعwheelie()يعيد"[brand] is doing a wheelie!"— وهذا سلوك فريد للدراجات النارية.main.php— قم بتضمين ملف Motorcycle (الذي يتضمن بالفعل Vehicle). ستتلقى مدخلاً واحداً: العلامة التجارية للدراجة النارية. قم بإنشاء كائنMotorcycleبهذه العلامة التجارية. اطبع نتيجة استدعاءstart()، ثمwheelie()، ثمstop()، كل منها في سطر مستقل.
لاحظ كيف ترث فئة Motorcycle تلقائياً خاصية $brand، والمنشئ، وكل من تابعي start() و stop() من Vehicle. تحتاج الفئة الفرعية فقط إلى تعريف ما يجعلها فريدة — في هذه الحالة، القدرة على القيام بحركة wheelie. هذه هي قوة التوريث: كتابة الوظائف المشتركة مرة واحدة في الفئة الأب، والسماح للأبناء بإعادة استخدامها مع إضافة تخصصاتهم الخاصة.
ورقة مرجعية
يسمح التوريث (Inheritance) للفئة بالحصول على الخصائص والأساليب من فئة أخرى باستخدام الكلمة المفتاحية extends. تُسمى الفئة التي يتم التوريث منها الفئة الأب (أو الفئة الأساسية)، وتُسمى الفئة التي تَرِث الفئة الابن.
<?php
class Animal {
public $name;
public function __construct($name) {
$this->name = $name;
}
public function speak() {
return "$this->name makes a sound";
}
}
class Dog extends Animal {
public function fetch() {
return "$this->name fetches the ball";
}
}
$dog = new Dog("Buddy");
echo $dog->speak(); // Buddy makes a sound
echo $dog->fetch(); // Buddy fetches the ball
ترث الفئة الابن جميع الأعضاء العامة (public) والمحمية (protected) من الأب، بما في ذلك الخصائص، والمنشئات (constructors)، والأساليب (methods). يمكن للفئة الابن أيضاً إضافة أساليبها وخصائصها المتخصصة.
يعزز التوريث إعادة استخدام الكود ويقيم علاقات منطقية بين الفئات، مما يقلل التكرار ويجعل صيانة الكود أسهل.
جرّب بنفسك
<?php
// تضمين فئة Motorcycle (التي تتضمن بالفعل Vehicle)
require_once 'Motorcycle.php';
// قراءة المدخلات
$brand = trim(fgets(STDIN));
// TODO: إنشاء كائن Motorcycle مع العلامة التجارية
// TODO: طباعة نتيجة start()
// TODO: طباعة نتيجة wheelie()
// TODO: طباعة نتيجة stop()
?>يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس Object Oriented Programming
1أساسيات OOP
الملفات الخارجيةمقدمة في OOPClasses مقابل Objectsالكلمة المفتاحية $thisالـ Methodsالـ Propertiesالمنشئ (__construct)الهادم (__destruct)مراجعة - آلة حاسبة بسيطة4الوراثة
الوراثة الأساسيةالكلمة المفتاحية parent::إعادة تعريف الدوال (Method Overriding)الكلمة المفتاحية finalالأصناف المجردة (Abstract Classes)مراجعة - هيكلية الموظفين7التغليف (Encapsulation)
العام، المحمي، الخاص (Public, Protected, Private)نظرة متعمقة على معدلات الوصولدوال Getters و Settersإخفاء المعلوماتميزة Constructor Promotion (8.0)مراجعة - نظام سجلات الطلاب10مفاهيم البرمجة كائنية التوجه المتقدمة
التركيب مقابل الوراثةحقن التبعيةالأصناف المجهولةالتعدادات (PHP 8.1)الألياف (PHP 8.1)تعمق في استنساخ الكائناتالمولدات والمكررات13أنماط التصميم - الجزء الثاني
نمط الأمرنمط المحولنمط المزيننمط طريقة القالبنمط الحالةنمط التركيبنمط المستودع2مساحات الأسماء والتحميل التلقائي
مقدمة إلى مساحات الأسماءالكلمة المفتاحية useمعيار التحميل التلقائي PSR-4أداة التحميل التلقائي Composerملخص - مشروع منظم5الواجهات والعقود
مقدمة إلى الواجهاتتنفيذ الواجهاتتنفيذ واجهات متعددةالواجهة مقابل الـ Abstract Classالـ Type Hinting مع الواجهاتملخص - حاسبة الأشكال8الميثودات السحرية (Magic Methods)
مقدمة في الميثودات السحرية__toString و __debugInfo__get, __set, __isset, __unset__call و __callStatic__clone واستنساخ الكائنات__serialize و __unserializeمراجعة - Custom Collection3خصائص الكلاس
خصائص الـ Instance مقابل الخصائص الساكنة (Static)الثوابت في الكلاساتالدوال والخصائص الساكنة (Static)الخصائص الخاصة (Private) والمحمية (Protected)خصائص للقراءة فقط (Readonly) في PHP 8.1مراجعة - مدير الحساب البنكي6تعدد الأشكال (Polymorphism)
مراجعة إعادة تعريف الدوال (Method Overriding)تعدد الأشكال عبر الـ Interfacesتلميح النوع (Type Hinting) وأنواع الاتحاد (Union Types)الربط الاستاتيكي المتأخر (Late Static Binding)ملخص - معالج الدفع (Payment Processor)