oop - متى يجب استخدام Final في PHP؟




(5)

هناك مقال لطيف حول "متى تعلن الفصول النهائية" . بعض الاقتباسات منه:

TL ؛ DR: اجعل فصولك دائمًا final ، إذا طبقت واجهة ، ولم يتم تحديد طرق عامة أخرى

لماذا يجب علي استخدام final ؟

  1. منع سلسلة الميراث الهائلة من الموت
  2. تكوين مشجع
  3. إجبار المطور على التفكير في API العامة للمستخدم
  4. فرض المطور لتقليص API العامة للكائن
  5. يمكن جعل الفصل final قابلاً للتوسعة دائمًا
  6. extends فواصل التغليف
  7. لا تحتاج هذه المرونة
  8. أنت حر في تغيير الرمز

متى يجب تجنب final :

لا تعمل الفصول النهائية بفعالية إلا في ظل الافتراضات التالية:

  1. هناك تجريد (واجهة) التي تنفذها الطبقة النهائية
  2. كل API العام للفئة النهائية هي جزء من تلك الواجهة

إذا كان أحد هذين الشرطين المسبقين مفقودًا ، فستصل على الأرجح إلى فترة زمنية تجعل الفصل الدراسي قابلاً للامتداد ، حيث أن الكود لا يعتمد حقًا على التجريد.

PS بفضلocramius لقراءتها كبيرة!

أعلم ما هو تعريف الفصل النهائي ، لكنني أريد أن أعرف كيف ومتى هناك حاجة إلى النهائي.

<?php
final class Foo extends Bar
{
   public function()
   {
     echo 'John Doe';
   }
}

إذا فهمت ذلك بشكل صحيح ، فإن "نهائي" يمكّنها من توسيع "فو".

هل يمكن لأي شخص أن يشرح متى ولماذا يجب استخدام كلمة "نهائي"؟ بمعنى آخر ، هل هناك أي سبب يمنع تمديد الفصل؟

على سبيل المثال ، إذا كانت الفئة "Bar" والفئة "Foo" تفتقدان لبعض الوظائف ، فسيكون من الجيد إنشاء فصل يمتد "Bar".


للاستخدام العام ، أوصي بعدم جعل الفصل "نهائيًا". قد تكون هناك بعض حالات الاستخدام حيث يكون من المنطقي: إذا قمت بتصميم واجهة برمجة تطبيقات / إطار عمل معقد وتريد التأكد من أن مستخدمي إطار العمل الخاص بك يمكنهم تجاوز أجزاء الوظيفة التي تريدهم التحكم فيها فقط ، فقد يكون من المنطقي بالنسبة لك تقييد هذا الاحتمال وجعل فئات أساسية معينة نهائية.

على سبيل المثال ، إذا كان لديك فئة "عدد صحيح" ، فقد يكون من المنطقي جعلها نهائية من أجل إبقاء مستخدمي نموذج إطار العمل الخاص بك يتغلبون على أسلوب "add (...)" في الفصل الدراسي.


الفصل النهائي هو الفصل الذي لا يمكن تمديده http://www.php.net/manual/en/language.oop5.final.php

يمكنك استخدامه حيث يحتوي الفصل على طرق لا تريد تجاوزها بالتحديد. قد يكون هذا بسبب قيامك بقطع التطبيق الخاص بك بطريقة ما.


السبب هو:

  1. إن إعلان الفصل على أنه نهائي يمنعه من أن يكون فئة فرعية. انها نهاية السطر.

  2. يسمح التصريح عن كل طريقة في الفصل كطريقة نهائية بإنشاء فئات فرعية لها حق الوصول إلى أساليب الفئة الأصل ، ولكن لا يمكنها تجاوزها. يمكن للفئات الفرعية تحديد طرق إضافية خاصة بها.

  3. تتحكم الكلمة الأساسية النهائية فقط في القدرة على التجاوز ويجب عدم الخلط بينها وبين معدِّل الرؤية الخاص. لا يمكن الوصول إلى طريقة خاصة من قبل أي فئة أخرى ؛ واحدة أخيرة يمكن.

—— مقتبسة من الصفحة 68 من كتاب حلول PHP Object-Oriented Solutions بواسطة David Powers .

فمثلا:

final childClassname extends ParentsClassname {
    // class definition omitted
}

يغطي هذا الفصل بأكمله ، بما في ذلك جميع أساليبه وخصائصه. أي محاولة لإنشاء فئة تابعة من childClassname قد ينتج عنها الآن خطأ فادح. ولكن ، إذا كنت بحاجة إلى السماح للفئة بأن تكون فئة فرعية ولكن تم منع أسلوب معين من تجاوزه ، فإن الكلمة الأساسية النهائية تظهر أمام تعريف الطريقة.

class childClassname extends parentClassname { 
    protected $numPages;

    public function __construct($autor, $pages) {
        $this->_autor = $autor;
        $this->numPages = $pages;
    }

    final public function PageCount() { 
        return $this->numPages; 
    }
}

في هذا المثال ، لن يتمكن أي منهم من تجاوز أسلوب PageCount() .


حاولت كتابة مثال بسيط لإظهار الفرق بين استخدام staticmethod و classmethod (وكذلك عدم استخدامها). هنا الرمز:

#without decorator:
class Duck(object):
    def sound(self):
        print("Quack")


#pay attention to the "sound" function:

#with @staticmethod
class Cat(object):
    @staticmethod
    def sound():
        print("Meow")

#with @classmethod
class Dog(object):
    @classmethod
    def sound(self):
        print("woof")


#notice the differences between calling them:
Duck().sound()
Cat.sound()
Dog.sound()

#prints:
"""
Quack
Meow
woof
"""




php oop final