Возможен ли окончательный метод статического класса? - PullRequest
2 голосов
/ 26 ноября 2011

Мне нужен класс для наследования другого класса.У меня есть статическая функция _init() в базовом классе, и я не хочу, чтобы этот метод наследовался в производном классе.Я попробовал ключевое слово final, но оно не работает.Что мне делать?

Ответы [ 6 ]

7 голосов
/ 26 ноября 2011

Вы неправильно понимаете, что означает финал.

Один из основополагающих принципов ООП заключается в том, что если класс является подклассом другого класса, то этот класс получает все функциональные возможности класса, от которого он наследует.Вы не можете унаследовать только некоторые функции суперкласса, это все или ничего.

Причина этого немного сложна для понимания, но как только вы это сделаете, вы поймете, что это имеет смысл.А именно, если кусок кода способен обрабатывать элементы определенного класса, то он также должен иметь возможность обрабатывать любой подкласс элемента.Если подкласс не обладает всей функциональностью своего суперкласса, вы не сможете этого сделать.

Например, представьте, что у вас есть класс, который определяет взаимодействие с платежным шлюзом.Поскольку все платежные шлюзы различны, вы не можете (или, по крайней мере, не должны) реализовать один класс, который может взаимодействовать с любым из доступных платежных шлюзов.Но в целом платежные шлюзы работают в основном так же.Запрос отправлен, включая данные кредитной карты пользователя и сумму, которую вы хотите снять с карты.Платежный шлюз отвечает сообщением о том, был ли платеж авторизован или нет.

Вы реализуете такую ​​функциональность с помощью абстрактного суперкласса, который определяет, как вы взаимодействуете с платежными шлюзами в целом, а затем создаете подкласс для каждого платежного шлюза, который вы хотите использовать (paypal, sagepay, что угодно).

Поскольку все эти подклассы наследуются от одного и того же базового класса, вы можете быть уверены, что все они реализуют определенные методы, и вы можете отправлять сообщения этим методам без беспокойства.Пока класс оплаты, с которым вы имеете дело, является подклассом вашего абстрактного класса оплаты, тогда все должно работать.

Если один из подклассов не смог реализовать что-либо из абстрактного суперкласса, то вы не могли быть уверены, что отправка определенного сообщения подклассу сработает или выдает исключение.Это сделало бы наследство довольно бессмысленным.

Окончательный вариант в PHP (и, действительно, большинство языков ООП, которые реализуют его или подобные концепции) означает: «Это конечная реализация этого метода. Если программист подклассирует меня, то он не может заменить мои окончательные методы своимисобственная реализация ».Это не значит, что методы не будут доступны в подклассе, просто вы не можете их изменить.

Если вам действительно нужно удалить функциональность из подкласса, вы можете сделать это, переопределив метод суперкласса и заменив его пустым методом (который ничего не делает).Но не делайте этого, так как это вызовет проблемы типа, описанного выше.

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

3 голосов
/ 26 ноября 2011

Статический означает один на класс, а не один для каждого объекта, независимо от того, сколько экземпляров класса может существовать.Это означает, что вы можете использовать их, не создавая экземпляр класса. Методы Stat неявно являются окончательными, поскольку переопределение выполняется на основе типа объекта, а статические методы присоединяются к классу, а не к объекту.Статический метод в суперклассе может быть затенен другим статическим методом в подклассе, если исходный метод не был объявлен как final.Однако вы не можете переопределить статический метод нестатическим методом.Другими словами, вы не можете изменить статический метод на метод экземпляра в подклассе.

Последний класс не может быть расширен, т. Е. Конечный класс не может быть разделен на подклассы.Последний метод не может быть переопределен, когда его класс наследуется.Вы не можете изменить значение конечной переменной (является константой).

3 голосов
/ 26 ноября 2011

Вы делаете это неправильно.

Тот факт, что у расширенного класса нет есть метод, означает, что вы нарушаете принцип подстановки Лискова .. если чтение затруднено: здесь картинка объясняющая это.

Если у вас есть ситуация, когда вам нужно выполнить какую-то «работу» над объектом до того, как вы выпустите его в приложение, тогда вы должны использовать для этого Factory / Builder.

class FooBuilder
{
   public function create( $external_condition )
   {
      $object = new Foo;
      if ( $external_condition->has_happened() )
      {
         $object->set_condition( $external_condition );
      }else{
         $object->do_something_else();
      }
      return $object;
   }
}

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

Кроме того, я бы сказал, что статические методы в классах являются признаком процедурного программирования. А статические переменные - это не что иное, как глобальные переменные, заключенные в пространство имен, маскирующиеся под класс.

2 голосов
/ 26 ноября 2011

В POO, если класс B наследует другой класс A, класс B будет содержать все методы из класса A, что является основой наследия POO. Так что I don't want that method to be inherited in the derived class не имеет здесь смысла. Вы должны посмотреть на другой механизм, чтобы сделать это.

Кроме того, в most случаях такая ситуация (когда вы не хотите, чтобы производный класс наследовал метод) является признаком того, что ваш производный класс вообще не должен наследовать, и где вам следует использовать другую систему.

1 голос
/ 26 ноября 2011

Я бы согласился с pomeh по ООП в PHP, а также хотел бы добавить, что ключевое слово FINAL при использовании с методом фактически означает, что метод не может быть переопределен.Метод будет унаследован, хотя.

1 голос
/ 26 ноября 2011

Проверьте этот пример:

class foo
{
  private static $stuff = array('key1' => 1, 'key2' => 2);

  public final static function getstuff()
  {
   return self::$stuff;
  }
}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...