У меня есть дочерний класс, который расширяет класс только статическими методами. Я хотел бы сделать этот дочерний класс синглоном, а не статичным, потому что первоначальный разработчик действительно хотел одноэлемент, но вместо него использовал статический (очевидно, потому что каждый метод в статическом классе вызывает функцию Init () (в основном конструктор)).
Большинство методов родителя не нужно перезаписывать в дочернем элементе, но я бы хотел не писать такие методы:
public function Load($id) { return parent::Load($id); }
когда я бы предпочел не переписывать метод вообще и просто использовать:
$child->Load($id);
Можно ли статически ставить статический метод не статически? Можно ли расширить статический объект с помощью экземпляра объекта? Я знаю, что могу попробовать, и это, скорее всего, будет работать (PHP очень прощает), но я не знаю, есть ли что-то, о чем я должен беспокоиться.
да
Да, но только с PHP 5.3 они работают так, как вы ожидаете: http://www.php.net/manual/en/language.oop5.static.php (т.е. self
привязывается к фактическому классу, а не к классу это определено в).
Да, но потеряет $this
. Вы не получаете предупреждение (пока), но также нет причин называть его неправильным способом.
Ответ на две части.
Во-первых, о титульном вопросе: вызов статического метода нестатически совершенно прекрасен; @ Комментарий SamDark верен. Он не предупреждает и не убивает котенка. Попробуй:
<?php class test { public static function staticwarnings(){ echo "YOU ARE (statically) WARNED!\n"; } } error_reporting(E_ALL); $test = new test(); echo "\n\ncalling static non-statically\n"; $test->staticwarnings();
Если у вас есть ссылка на экземпляр, $this
, в этом статическом методе, то вы получите фатальную ошибку. Но это верно независимо от того, как вы это называете.
Еще раз, нет предупреждения, ни котенка не убили.
Вторая часть ответа:
Вызов переопределенной родительской функции из переопределяющего дочернего класса требует чего-то, называемого « разрешение области » . То, что OP делает в своем методе, не вызывает статический метод. (Или, по крайней мере, это не обязательно, мы не можем видеть родительскую реализацию). Дело в том, что использование ключевого слова parent не является статическим вызовом. Использование оператора ::
на явном имени родительского класса также не является статическим вызовом, если он используется из расширяющегося класса.
Почему эта документальная ссылка так странно названа? Это буквально иврит. Если вы когда-либо сталкивались с ошибкой, связанной с этим, вы могли бы заметить код ошибки парсера с восхищенным именем T_PAAMAYIM_NEKUDOTAYIM
.