الكثير ممن يبدأ في تعلم البرمجة الكائنية PHP OOP يتعرض لبعض المفاهيم التي ربما يكون قد عرف كيفية عملها ولكن لايعرف ما هو المغذى أو الجدوى الحقيقية من استخدامها في برنامج، ومن هذه المفاهيم التوريث PHP Inheritance.
كما نعرف أن التوريث هو عملية توريث كلاس ما PHP class إلى كلاس أخرى ولكن يطرأ على العقل سؤالاً وهو ، لماذا استخدم التوريث عملياً؟
في الحقيقة الموضوع معتمد على دراستك للبرنامج وتخطيطك له، بحيث تعرف مسبقاً ما هي الوظائف المطلوبة منه، وأثناء التخطيط تبين لك أن هناك بعض الوظائف سوف تكون مشتركة بين مجموعة من الكائنات، مع العلم أن كل كائن له وظائفه وخصائصه المميزة، وبالتالي تحتاج لعمل كلاس تحتوي على الخصائص والوظائف المشتركة ثم تبدأ بالتوريث للكلاسات حسب كل كائن واختلاف خصائصه ووظائفه عن الآخر.
مثلاً، ربما تفكر في ما هي جدوى التوريث إذا كان بالإمكان إضافة الخصائص والوظائف الجديدة إلى الكلاس الأساسية مباشرة، وبالتالي أي كائن منها سيكون له إمكانية استخدامها، لكن هذا غير سليم بالمرة.
نفترض أنك قمت ببناء كلاس للموظفين في الشركة تحتوي على خصائص الموظفين المشتركة مثل ( الراتب – مواعيد العمل – لون الزي – القسم التابع له ) وأيضاً بعض الوظائف المشتركة لجميع الموظفين مثل ( تسجيل الحضور والإنصراف – استلام الراتب)، ثم تريد عمل أكثر من كائن من هذه الكلاس (أكثر من نموذج لموظف) بحيث يكون لديك:
نموذج للمدير: الذي يقوم بمتابعة شؤون العمل ومنح المكافئات أو توقيع الجزاءات ونموذج لموظف قسم المبيعات: الذي يقوم بمتابعة مبيعات الشركة وعمل حملات ترويجية ونموذج للسائق: ومسؤل عن قيادة سيارة نقل المنتجات وآخر لعامل البوفيه: وهذا طبعا يقوم بتجهيز مشوبات الموظفينالآن إذا تخيلنا أننا سنقوم ببناء كلاس للموظفين ووضعنا داخلها الخصائص والوظائف لكل موظف بهذا الشكل
<?php class EMPLOYER{ public $salary, $working_hours, $uniform, $department public function __construct(){ //constructor code } public function login(){ //login code } public function logout(){ //logout code } public function get_salary(){ //get_salary code } //manager job public function manage(){ //manage code } //sales employer job public function sell(){ //sell code } //driver job public function drive(){ //drive code } //tea boy job public function make_drinks(){ //make_drinks code } } ?>نفرض الآن أنك تريد عمل كائن خاص بعامل البوفيه tea boy
$tea_by = new EMPLOYER();أليس الآن يستطيع عامل البوفيه إدارة الشركة؟!! لأنه يمكنه الوصول للدالة $tea_boy->manage(); ، وهذا غير منطقي، لذلك يجب عليك استخدام التوريث هنا بحيث تكون الخصائص والطرق المشتركة بين الكائنات موجودة في كلاس أساسية Base class ثم تقوم بالتوريث لكلاس أخرى بحيث هذه الكلاس سيتم عمل كائنات منها. وبالتالي سيكون لكل كائن نفس خصائص وطرق الكلاس الأساسية وأيضاً خصائصه وطرقه المميزة، فيكون شكل الكود الآن
<?php class EMPLOYER{ public $salary, $working_hours, $uniform, $department public function __construct(){ //constructor code } public function login(){ //login code } public function logout(){ //logout code } public function get_salary(){ //get_salary code } } class Manager extends EMPLOYER{ public function __construct(){ //constructor code } //manager job public function manage(){ //manage code } } class Sales_Employer extends EMPLOYER{ public function __construct(){ //constructor code } //sales employer job public function sell(){ //sell code } } class Driver extends EMPLOYER{ public function __construct(){ //constructor code } //driver job public function drive(){ //drive code } } class Tea_Boy extends EMPLOYER{ public function __construct(){ //constructor code } //tea boy job public function make_drinks(){ //make_drinks code } } $tea_by = new Tea_Boy(); $tea_boy->get_salary();//succeeds $tea_boy->make_drinks();//succeeds $tea_boy->manage();//Fails ?>لاحظ في السطرين 54 و 55 نجاح الكائن $tea_boy في الوصول للدالتين get_salary() و make_drinks() لأن الأول موجودة في الكلاس الأساسية (الكلاس الأب) والثانية تم تعريفها في الكلاس الخاصة بـ Tea_Boy لكن الآن لايستطيع الوصول للدالة manage() لأنها غير موجوده في الكلاس الأساسية (الكلاس الأب) ولا الكلاس Tea_Boy
أيضاً من فوائد التوريث هو الإستفادة من أسلوب التخطي PHP Method Overriding بحيث يمكن أن تجعل كل كائن يقوم بالوظيفة بشكل مختلف، وليكن الكائن من الكلاس Manager يقوم باستلام الراتب get_salary() عن طريق تحويل بنكي بينما باقي الموظفين يتم استلام الراتب من المحاسب. وبالتالي يفضل أن تجع السلوك الإفتراضي للدالة get_salary() هو إشعار الموظفين كلهم بالذهاب للمحاسب بينما تعيد تعريف الدالة مرة أخرى داخل كلاس Manager ولكن لتحويل الراتب للبنك.
<?php class EMPLOYER{ public $salary, $working_hours, $uniform, $department public function __construct(){ //constructor code } public function login(){ //login code } public function logout(){ //logout code } public function get_salary(){ echo 'Please, receive your salary from the accountant' } } class Manager extends EMPLOYER{ public function __construct(){ //constructor code } //manager job public function manage(){ //manage code } public function get_salary(){ echo 'Your salary has been transfered to your bank account' } } ?>لاحظ أنك إذا قمت بتغيير سلوك الدالة get_salary() في الكلاس الاساسية يؤثر على جميع الكائنات المشتقة منها وبالتالي أهمية التوريث تظهر عند الحاجة لتغيير سلوك فئة معينة من الكائنات عن السلوك الإفتراضي للكائنات المشتقة من الكلاس الاساسية، وهذا ما قمنا به عند تغيير سلوكها في الكلاس Manager.
أيضاً من مميزات التوريث أنه إذا كان هناك كود يتم تطبيقه على كائن من الكلاس الأساسية Base Class، فإن التوريث يسمح لك بتنفيذ نفس الكود على كائن من الكلاس الوارثة بدون مشاكل.

