diff --git a/language/oop5/late-static-bindings.xml b/language/oop5/late-static-bindings.xml index ee40e00d7..0377991ec 100644 --- a/language/oop5/late-static-bindings.xml +++ b/language/oop5/late-static-bindings.xml @@ -1,69 +1,74 @@ - + Позднее статическое связывание - PHP реализует функцию, называемую позднее статическое - связывание, которая может быть использована для того, чтобы получить ссылку на - вызываемый класс в контексте статического наследования. + Позднее статическое связывание в PHP — механизм, который разрешает ссылаться + на класс вызова в контексте статического наследования. - Если говорить более точно, позднее статическое связывание сохраняет имя класса - указанного в последнем "неперенаправленном вызове". В случае статических - вызовов это явно указанный класс (обычно слева от оператора - ::); - в случае не статических вызовов это класс объекта. "Перенаправленный вызов" - это - статический вызов, начинающийся с self::, parent::, - static::, или, если двигаться вверх по иерархии классов, - forward_static_call. - - - Функция get_called_class может быть использована для - получения строки с именем вызванного класса, а static:: - представляет её область действия. + Точнее, позднее статическое связывание сохраняет класс, + название которого указали в последнем «неперенаправленном вызове». При вызове статических + методов это тот класс, название которого явно указали слева от оператора + ::; + при нестатических вызовах это класс объекта. «Перенаправленным вызовом» называется + статический вызов через конструкции self::, parent::, + static:: или через функцию forward_static_call + при движении вверх по иерархии классов. + + + Строку с названием класса вызова получают функцией get_called_class, + а конструкция static:: вводит область действия вызываемого класса. - Само название "позднее статическое связывание" отражает в себе внутреннюю - реализацию этой особенности. "Позднее связывание" отражает тот факт, что - обращения через static:: не будут вычисляться по отношению - к классу, в котором вызываемый метод определён, а будут вычисляться на основе - информации в ходе исполнения. - - Также эта особенность была названа "статическое связывание" потому, что она - может быть использована (но не обязательно) в статических методах. + Природа названия «позднее статическое связывание» возникает из внутренней + логики работы языка. Связывание называется «поздним», потому что конструкция static:: + разрешается не в тот класс, в котором определили метод, + а вычисляется на основе информации в ходе исполнения программы. + + Связывание также назвали «статическим», поскольку + этот механизм в числе прочего умеет вызывать статические методы. - Ограничения <literal>self::</literal> + Ограничения конструкции <literal>self::</literal> - Статические ссылки на текущий класс, такие как self:: - или __CLASS__, вычисляются используя класс, - к которому эта функция принадлежит, как и в том месте, где она была определена: + Статические ссылки на текущий класс наподобие конструкции self:: + или константы __CLASS__ разрешаются в класс, + которому принадлежит функция, — в котором функцию определили: - Использование <literal>self::</literal> + Пример обращения к члену класса через конструкцию <literal>self::</literal> ]]> @@ -78,38 +83,46 @@ A - Использование позднего статического связывания + Пример позднего статического связывания - Позднее статическое связывание пытается устранить это ограничение, предоставляя - ключевое слово, которое ссылается на класс, вызванный непосредственно в - ходе выполнения. Попросту говоря, ключевое слово, которое позволит вам - ссылаться на B из test() в - предыдущем примере. Было решено не вводить новое ключевое слово, а - использовать static, которое уже зарезервировано. + Позднее статическое связывание стремится устранить это ограничение и вводит + ключевое слово для ссылки на класс, который изначально вызвали + в ходе исполнения программы. По сути, это ключевое слово, которое в предыдущем примере + разрешило бы ссылаться на класс B из метода test(). + Вместо введения нового ключевого слова для позднего статического связывания разработчики языка выбрали + ключевое слово static, которое зарезервировали прежде. - Простое использование <literal>static::</literal> + Пример позднего статического связывания через конструкцию <literal>static::</literal> ]]> @@ -122,99 +135,122 @@ B - В нестатическом контексте вызванным классом будет тот, к которому - относится экземпляр объекта. Поскольку $this-> - будет пытаться вызывать закрытые методы из той же области действия, - использование static:: может дать разные результаты. - Другое отличие в том, что static:: может ссылаться - только на статические поля класса. + В нестатическом контексте классом вызова будет класс + экземпляра объекта. Обращение через конструкцию $this-> + попытается вызывать закрытые методы из той же области действия, + тогда как результат конструкции static:: зависит от контекста вызова. + Другое отличие состоит в том, что обращение через конструкцию static:: + умеет ссылаться только на статические элементы класса. - Использование <literal>static::</literal> в нестатическом контексте + Пример ссылки через конструкцию <literal>static::</literal> в нестатическом контексте foo(); static::foo(); } } -class B extends A { - /* foo() будет скопирован в В, следовательно его область действия по прежнему А, - и вызов будет успешным */ +class B extends A +{ + /* Метод foo() скопируется в класс В из класса A, поэтому областью действия метода + по-прежнему будет класс А, и вызов будет успешным */ } -class C extends A { - private function foo() { - /* исходный метод заменён; область действия нового метода - С */ +class C extends A +{ + private function foo() + { + /* Этот метод заменил собой исходный; область действия нового метода — класс С */ } } $b = new B(); $b->test(); + $c = new C(); -$c->test(); // потерпит ошибку +try { + $c->test(); +} catch (Error $e) { + echo $e->getMessage(); +} + ?> ]]> &example.outputs; - Разрешающая область позднего статического связывания будет - фиксирована вычисляющем её статическим вызовом. С другой стороны, - статические вызовы с использованием таких директив как parent:: - или self:: перенаправляют информацию вызова. + Разрешение поздних статических связок останавливается на статическом вызове по полному названию класса, + без попытки перенаправить вызов в класс, в котором сделали последний неперенаправленный вызов. Между тем, + статические вызовы через конструкции parent:: + или self:: перенаправляют информацию о вызове. - Перенаправленные и неперенаправленные вызовы + Пример перенаправленных и неперенаправленных вызовов ]]>