In addition to restricting access, the access method also determines which method will be called by the subclass or which property will be accessed by the subclass. The relationship between function calls and the function itself, and the relationship between member access and variable memory addresses, is called binding.
There are two main types of binding in computer languages - static binding and dynamic binding. Static binding occurs between data structures and data structures before the program is executed. Static binding occurs at compile time and therefore cannot utilize any runtime information. It targets function calls and the body of a function, or variables and blocks of memory. Because PHP is a dynamic language, it does not use static binding. But static binding can be simulated.
Dynamic binding uses only available information at runtime for access requests generated during runtime. In object-oriented code, dynamic binding means that the decision about which method is called or which property is accessed will be based on the class itself and not on the access scope.
The actions of public and protected members are similar to the actions of functions in previous versions of PHP, using dynamic binding. This means that if a method accesses a class member that is overridden in a subclass and is an instance of the subclass, the subclass member will be accessed (instead of accessing the member in the parent class).
Look at Example 6.10. This code outputs "Hey! I am Son." Because when PHP calls getSalutation, it is an instance of Son, which overwrites the salutation in Father. If the salutation is public, PHP will generate the same Result. The operation of the overridden method is very similar. In Son, calls to identify are bound to that method.
Even if the access method is weakened from protected to public in a subclass, dynamic binding will still occur. According to the principle of using access methods, it is impossible to enhance the access restrictions on class members, so changing the access method from public to protected does not May proceed.
Listing 6.10 Dynamic binding dynamic binding
class Father
{
protected $salutation = "Hello there!"; //Greetings
public function getSalutation()
{
print("$this->salutationn");
$this->identify();
}
protected function identify()
{
print("I am Father.
n");
}
};
class Son extends Father
{
protected $salutation = "Hey!"; //protected $salutation in the parent class is overwritten
protected function identify() //protected identify() in the parent class is overwritten
{
print("I am Son.
n");
}
};
$obj = new Son();
$obj->getSalutation(); //Output Hey! I am Son.
?>
//Note: getSalutation() is not overridden in the subclass, but there is actually still a getSalutation(). $salutation and identify() in this class
//Dynamically bound to the getSalutation() method in the instance of the Son subclass, so the getSalutation() method of the Son instance is called,
//The member salutation and identify() in the Son class will be called instead of the member salutation and identify() in the parent class.
Private members only exist inside the class in which they are located. Unlike public and protected members, PHP simulates static Binding. See Example 6.11. It prints "Hello there! I am Father." Although the subclass overwrites the value of the salutation, the script binds this->salutation to the current class Father. A similar principle applies to the private method identify().
Listing 6.11 Binding and private members
class Father
{
private $salutation = "Hello there!";
public function getSalutation()
{
print("$this->salutationn");
$this->identify();
}
private function identify()
{
print("I am Father.
n");
}
}
class Son extends Father
{
private $salutation = "Hey!";
private function identify()
{
print("I am Son.
n");
}
}
$obj = new Son();
$obj->getSalutation(); //Output Hello there! I am Father.
?>
The advantage of dynamic binding is that it allows inherited classes to change the behavior of the parent class while maintaining the interface and functions of the parent class. See Example 6.12. Due to the use of dynamic binding, the version of isAuthorized called in deleteUser can be Determined by the type of object. If it is an ordinary user, PHP calling User::isAuthorized will return FALSE. If it is an instance of AuthorizedUser, PHP calling AuthorizedUser::isAuthorized will allow deleteUser to execute smoothly.
//haohappy Note: To put it clearly in one sentence, it is object type and method, attribute binding. When calling a method that exists in both the parent class and the subclass or accessing an attribute, it will first determine which object type the instance belongs to, and then call Methods and properties in the corresponding class.
Listing 6.12 Benefits of dynamic binding
class User //User
{
protected function isAuthorized() //Whether it is an authenticated user
{
return(FALSE);
}
public function getName() //Get the name
{
return($this->name);
}
public function deleteUser($username) //Delete user
{
if(!$this->isAuthorized())
{
print("You are not authorized.
n");
return(FALSE);
}
//delete the user
print("User deleted.
n");
}
}
class AuthorizedUser extends User //Authentication user
{
protected function isAuthorized() //overwrite isAuthorized()
{
return(TRUE);
}
}
$user = new User;
$admin = new AuthorizedUser;
//not authorized
$user->deleteUser("Zeev");
//authorized
$admin->deleteUser("Zeev");
?>
Why do private class members simulate static binding? To answer this question, you need to recall why you need to have private members. When does it make sense to use them instead of protected members?
Private members only if you don't want subclasses to inherit Used only when changing or specializing the behavior of a parent class. This is less common than you might think. Generally speaking, a good object hierarchy should allow most functionality to be specialized, improved, or changed by subclasses— This is one of the foundations of object-oriented programming. Private methods or variables are needed in certain situations, such as when you are sure that you do not want to allow a subclass to change a specific part of the parent class.