6.9. Связывание
Кроме ограничения доступа, типы доступа определяют вызываемые метод и свойство в подклассах, в которых методы или свойства будут перекрываться. Определение связи между вызовами функций и соответствующими им функциями и между доступом к элементам и распределением памяти для переменных называется связыванием.
В языках программирования существуют два основных метода связывания - статическое и динамическое. Статическое связывание устанавливает связь между ссылками на структуры данных и самими структурами данных. Статическое связывание устанавливается при компиляции и, естественно, не может использовать динамическую информацию, поступающую при выполнении программы. Оно ставит в соответствие вызовам функций тела функций и переменные своим блокам памяти. Так как PHP является динамическим языком программирования, он не может использовать статическое связывание, однако есть возможность эмулировать статическое связывание.
Динамическое связывание подбирает запросы на осуществление доступа во время выполнения, пользуясь при этом информацией, которую можно получить только во время выполнения программы. В контексте объектно-ориентированного кода динамическое связывание обозначает определение вызываемого метода или свойства, к которому осуществляется доступ на основании класса this, а не на основании диапазона, в котором производится доступ.
Общедоступные и защищенные элементы ведут себя аналогично поведению методов в предыдущих версиях PHP и связаны с применением динамического связывания. Это означает, что если метод осуществляет доступ к элементу класса, перекрытому в порожденном классе, и наш указатель this является экземпляром порожденного класса, то порожденный элемент будет доступен.
Рассмотрим листинг 6.10. Содержащийся там код выводит на печать "Привет! Я сын. ", так как когда PHP достигает getSalutation, this будет экземпляром Son, который перекроет существующее значение salutation. Если salutation была общедоступной, PHP даст идентичные результаты. Перекрытие метода осуществляется подобным образом. Вызов identify связывает с методом в Son.
Динамическое связывание происходит даже тогда, когда тип доступа в порожденных классах снижается с защищенного до общедоступного. В соответствии с правилами работы с типами доступа расширять права доступа к элементам класса невозможно. Таким образом, изменение типа доступа от общедоступного к защищенному невозможно.

| Листинг 6.10. Динамическое связывание_
<?php
class Father
{
protected $salutation = "Привет всем!"; public function getSalutation()

print("$this->salutationn"); $this->identify();
}
protected function identify()
{
printer отец. <br>n");
}
};
class Son extends Father
{
protected $salutation = " Привет!"; protected function identify()
{
print("Я сын. <br>n");
}
};
$obj = new Son(); $obj->getSalutation();
?>

Частные методы существуют только в пределах своего класса. В отличие от общедоступных и защищенных элементов, PHP позволяет эмулировать статическое связывание для частных элементов классов. Обратимся к листингу 6.11. Несмотря на перекрытие классом Child значения salutation, он все-таки выводит на печать "Привет! Я отец". Сценарий должен связывать this->salutation непосредственно с классом Father. Аналогичные правила применимы к частному методу identify.

| Листинг 6.11. Связывание и частные методы
<?php
class Father
{
private $salutation = " Привет!"; public function getSalutation()
{
print("$this->salutationn"); $this->identify();
}
private function identify()
{
print(" Я отец. <br>n");
}
}
class Son extends Father
{
private $salutation = " Привет!"; private function identify()
{
print(" Я сын. <br>n");
}
}
$obj = new Son(); $obj->getSalutation();
Преимущество динамического связывания заключается в том, что оно позволяет порожденным классам изменять поведение своих "предков", сохраняя при этом все преимущества их интерфейсов и функциональности. Рассмотрим листинг 6.12. Благодаря динамическому связыванию версия isAuthorized, вызванная внутри deleteUser, определяется на основании типа нашего объекта. Если this относится к обычному пользователю, PHP вызывает конструкцию User::isAuthorized, которая возвращает значение FALSE. Если this является экземпляром AuthorizedUser, PHP вызывает конструкцию AuthorizedUser::isAuthorized, которая позволит работать deleteUser в требуемом режиме.

| Листинг 6.12. Преимущества динамического связывания_
<?php
class User
{
protected function isAuthorized()
{
return(FALSE);
}
public function getName()
{
return($this->name);
}
public function deleteUser($username)
{
if(!$this->isAuthorized())
{
print("E>bi не имеете права. <br>n"); return(FALSE);
}
// удалить пользователя
print(" Пользователь удален. <br>n");
}
}
class AuthorizedUser extends User
{
protected function isAuthorized()
{
return(TRUE);
}
}
$user = new User;
$admin = new AuthorizedUser;
// не имеет права
$user->deleteUser("Zeev");
// имеет право
$admin->deleteUser("Zeev");
?>

 Зачем частные классы эмулируют статическое связывание? Для того чтобы ответить на этот вопрос, сначала необходимо вспомнить причины появления на свет частных элементов, т.е. когда приемлемо использовать их вместо защищенных элементов. Пользуйтесь частными элементами только тогда, когда вы не хотите, чтобы порожденные классы меняли или каким-то образом ограничивали поведение порождающего класса. Таких случаев не так уж и много. В общем, хорошая иерархия объектов должна позволять дорабатывать, улучшать или изменять большую часть функциональности из порожденных классов. Это является одним из основополагающих моментов ООП. В некоторых случаях, когда разработчик не хочет, чтобы порожденные классы имели возможность вносить изменения в определенные аспекты класса, требуются частные методы или переменные.