Когда использовать Final в PHP? - PullRequest
50 голосов
/ 22 ноября 2010

Я знаю, каково определение класса Финал, но я хочу знать, как и когда действительно нужен финал.

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

Если я правильно понимаю, «final» позволяет расширить «Foo».

Может кто-нибудь объяснить, когда и почему следует использовать «финал»? Другими словами, есть ли причина, по которой класс не следует расширять?

Если, например, в классе 'Bar' и классе 'Foo' отсутствуют некоторые функции, было бы неплохо создать класс, который расширяет 'Bar'.

Ответы [ 4 ]

45 голосов
/ 18 ноября 2015

Есть хорошая статья о "Когда объявлять классы final" . Несколько цитат из него:

TL; DR: Делайте ваши классы всегда final, если они реализуют интерфейс, и никакие другие открытые методы не определены

Почему я должен использовать final?

  1. Предотвращение массивной цепочки наследства гибели
  2. Обнадеживающая композиция
  3. Заставить разработчика задуматься о публичном API пользователя
  4. Заставить разработчика сократить общедоступный API объекта
  5. A final класс всегда можно сделать расширяемым
  6. extends нарушает инкапсуляцию
  7. Вам не нужна эта гибкость
  8. Вы можете изменить код

Когда следует избегать final:

Итоговые занятия эффективно работают только при следующих допущениях:

  1. Существует абстракция (интерфейс), которую реализует последний класс
  2. Все общедоступные API финального класса являются частью этого интерфейса

Если одно из этих двух предварительных условий отсутствует, то вы, вероятно, достигнете момента времени, когда вы сделаете класс расширяемым, поскольку ваш код действительно не полагается на абстракции.

P.S. Спасибо @ocramius за отличное чтение!

18 голосов
/ 22 ноября 2010

Для общего использования я бы рекомендовал не делать класс "финальным". Могут быть случаи, когда это имеет смысл: если вы разрабатываете сложный API / каркас и хотите убедиться, что пользователи вашей каркаса могут переопределять только те части функциональности, которые вы хотите, чтобы они контролировали, это может иметь смысл ограничьте эту возможность и сделайте определенные базовые классы окончательными.

например. если у вас есть класс «Integer», возможно, имеет смысл сделать этот финал, чтобы пользователи вашей структуры фреймворка переопределяли, скажем, метод «add (...)» в вашем классе.

10 голосов
/ 01 февраля 2016

Причина:

  1. Объявление класса как окончательного предотвращает его подклассы - точка;это конец строки.

  2. Объявление каждого метода в классе как конечного позволяет создавать подклассы, которые имеют доступ к методам родительского класса, но не могут их переопределять.Подклассы могут определять свои собственные дополнительные методы.

  3. Последнее ключевое слово контролирует только возможность переопределения и не должно быть перепутано с модификатором приватной видимости.Закрытый метод не может быть доступен любому другому классу;последний может.

- цитата со страницы 68 книги Объектно-ориентированные решения PHP Дэвид Пауэрс .

Например:

final childClassname extends ParentsClassname {
    // class definition omitted
}

Это охватывает весь класс, включая все его методы и свойства.Любая попытка создать дочерний класс из childClassname теперь приведет к фатальной ошибке.Но если вам нужно разрешить разделить класс на подклассы, но предотвратить переопределение определенного метода, ключевое слово final будет идти перед определением метода.

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().

5 голосов
/ 22 ноября 2010

Последний класс - это класс, который не может быть продлен http://www.php.net/manual/en/language.oop5.final.php

Вы должны использовать его там, где класс содержит методы, которые вы не хотите переопределять. Это может быть из-за того, что выполнение do каким-то образом сломает ваше приложение.

...