Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

مقدمة إلى السمات

جزء من قسم البرمجة كائنية التوجه في رحلة PHP على Coddy. الدرس 51 من 91.

تدعم PHP الوراثة الأحادية فقط — إذ يمكن لـ class أن ترث من class أب واحد فقط. ولكن ماذا لو احتجت إلى مشاركة الوظائف بين عدة فئات غير مرتبطة؟ هنا يأتي دور traits.

إن trait آلية لإعادة استخدام الشيفرة تتيح لك define أساليب method وخصائص property يمكن إدراجها في عدة class. فكّر في trait على أنه نسخ ولصق على مستوى اللغة — إذ تصبح الشيفرة من trait جزءًا من class الذي يستخدمه.

<?php
trait Timestampable {
    private string $createdAt;
    
    public function setCreatedAt(): void {
        $this->createdAt = date('Y-m-d H:i:s');
    }
    
    public function getCreatedAt(): string {
        return $this->createdAt;
    }
}

class Article {
    use Timestampable;
    
    public function __construct(public string $title) {
        $this->setCreatedAt();
    }
}

$article = new Article("PHP Traits");
echo $article->getCreatedAt();

تستورد الكلمة المفتاحية use داخل class أعضاء trait. والآن يمكن لـ Article الوصول إلى setCreatedAt() وgetCreatedAt() كما لو أنهما معرّفان مباشرةً في class.

يمكن استخدام نفس trait في فئات غير مترابطة تمامًا — فئة Comment، أو فئة User، أو أي فئة أخرى تحتاج إلى وظائف الطوابع الزمنية. وهذا يحلّ قيد الوراثة الأحادية من خلال السماح بمشاركة الشيفرة أفقيًا عبر تسلسل الفئات لديك.

challenge icon

التحدي

سهل

لنبنِ نظام تحية بسيطًا يوضّح كيف تتيح لك traits مشاركة الوظائف عبر classes غير المرتبطة. ستنشئ trait يوفر إمكانية التحية، ثم تستخدمه في classين مختلفين تمامًا.

ستنظّم الشيفرة عبر ثلاثة ملفات:

  • Greetable.php: أنشئ trait called Greetable يوفر وظيفة التحية. يجب أن يحتوي trait على:
    • خاصية private باسم $greeting من النوع string
    • method باسم setGreeting(string $greeting) تخزّن رسالة التحية
    • method باسم greet() returns رسالة التحية
  • Person.php: أنشئ class باسم Person يستخدم trait Greetable. أدرج ملف trait واستخدم constructor promotion لتعريف خاصية public باسم $name. في constructor، استدعِ setGreeting() لتعيين التحية إلى "Hello, I'm [name]".
  • Robot.php: أنشئ class باسم Robot يستخدم أيضًا trait Greetable. أدرج ملف trait واستخدم constructor promotion لتعريف خاصية public باسم $model. في constructor، استدعِ setGreeting() لتعيين التحية إلى "Beep boop, I am model [model]".

في main.php، أدرج ملفَي class. ستتلقى مُدخلين: اسم شخص ورقم model لروبوت. أنشئ مثيلين من كلا classين واطبع تحياتهما في سطرين منفصلين.

يوضّح هذا قوة traits: إن Person وRobot classان غير مرتبطين تمامًا ولا يملكان parent مشتركًا، ومع ذلك يكتسب كلاهما وظيفة التحية نفسها من خلال trait. يخصص كل class طريقة استخدامه لهذه الوظيفة بأسلوبه الخاص.

جرّب بنفسك

<?php

require_once 'Person.php';
require_once 'Robot.php';

// اقرأ المدخلات
$name = trim(fgets(STDIN));
$model = trim(fgets(STDIN));

// TODO: أنشئ كائن Person بالاسم المعطى
// TODO: أنشئ كائن Robot بالنموذج المعطى
// TODO: اطبع تحية Person
// TODO: اطبع تحية Robot (في سطر جديد)

?>
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: مترجم PHP عبر الإنترنت