الفرق بين المراجعتين لصفحة: «PHP/abstract»
ط استبدال النص - 'PHP/OOP/visibility' ب'PHP/properties visibility' |
ط نقل عبد اللطيف ايمش صفحة PHP/OOP/abstract إلى PHP/abstract: إعادة هيكلة التوثيق |
(لا فرق)
|
مراجعة 03:50، 4 أبريل 2018
يقدّم الإصدار الخامس من اللغة الأصناف والتوابع المجرّدة. لا يمكن تهيئة الأصناف المجرّدة، وإذا احتوى الصنف على تابع مجرّد واحدٍ على الأقل فيجب أن يكون الصنف مجردًا أيضًا. تصرّح الأصناف المجرّدة ببساطة عن توقيع التابع (method's signature)، ولا يمكنها تعريف الاستخدام (implementation).
عندما يرث صنفٌ من صنفٍ مجرّد، يجب تعريف جميع التوابع المجرّدة في الصنف الأب ضمن الصنف الابن، إضافة إلى وجوب تعريف هذه الأصناف بنفس مستوى قابلية الرؤية (أو بمستوى أقل محدودية). فعلى سبيل المثال، إن كان التابع المجرّد من نوع protected فإن تطبيق الدالة (أي تعريفها وإضافة الشيفرة الخاصة بها) يجب أن يكون من نوع protected أو public، ولا يمكن أن يكون من نوع private. بالإضافة إلى ذلك يجب أن تتطابق تواقيع التوابع كذلك، بمعنى أنّ التلميح عن النوع (type hint) وعدد المعاملات المطلوبة يجب أن يكون متشابهًا. فمثلاً، إن تضمن تعريف الصنف الابن معاملًا اختياريًا، في حين أن توقي التابع المجرد لا يتضمن مثل هذا المعامل، فلا وجود لأي تعارض في التوقيع. ينطبق هذا الأمر أيضًا على التوابع البانية في الإصدار 5.4 من اللغة، أما في الإصدارات السابقة فيمكن أن يحدث اختلاف في توقيعات التوابع البانية.
المثال 1: مثال على صنف مجرد.
<?php
abstract class AbstractClass
{
// يجب توسيع الصنف لتعريف هذا التابع
abstract protected function getValue();
abstract protected function prefixValue($prefix);
// تابع مشترك
public function printOut() {
print $this->getValue() . "\n";
}
}
class ConcreteClass1 extends AbstractClass
{
protected function getValue() {
return "ConcreteClass1";
}
public function prefixValue($prefix) {
return "{$prefix}ConcreteClass1";
}
}
class ConcreteClass2 extends AbstractClass
{
public function getValue() {
return "ConcreteClass2";
}
public function prefixValue($prefix) {
return "{$prefix}ConcreteClass2";
}
}
$class1 = new ConcreteClass1;
$class1->printOut();
echo $class1->prefixValue('FOO_') ."\n";
$class2 = new ConcreteClass2;
$class2->printOut();
echo $class2->prefixValue('FOO_') ."\n";
?>
تعطي الشيفرة السابقة المخرجات التالية:
ConcreteClass1
FOO_ConcreteClass1
ConcreteClass2
FOO_ConcreteClass2
المثال 2: مثال على صنف مجرّد
<?php
abstract class AbstractClass
{
// يحتاج التابع المجرد إلى تعريف المتغيرات المطلوبة فقط
abstract protected function prefixName($name);
}
class ConcreteClass extends AbstractClass
{
// يمكن للصنف الابن أن يعرّف معاملات اختياري غير موجودة في توقيع التابع الأب
public function prefixName($name, $separator = ".") {
if ($name == "Pacman") {
$prefix = "Mr";
} elseif ($name == "Pacwoman") {
$prefix = "Mrs";
} else {
$prefix = "";
}
return "{$prefix}{$separator} {$name}";
}
}
$class = new ConcreteClass;
echo $class->prefixName("Pacman"), "\n";
echo $class->prefixName("Pacwoman"), "\n";
?>
تعطي الشيفرة السابقة النتائج التالية:
Mr. Pacman
Mrs. Pacwoman
تعمل الشيفرة القديمة التي لا توجد فيها أصناف معرّفة من قبل المستخدم أو دوال تحمل الاسم 'abstract
' دون أي تعديلات.