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.
In computer language There are two main ways of binding? 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, so it cannot use any runtime information. It targets function calls and the body of the function, or variables and blocks in memory. Because PHP is a dynamic language, it does not use static binding. However, it can simulate static binding.
Dynamic binding targets access generated during runtime
.Requests only use information available at 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.
Public and protected members Actions are similar to function actions 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 is accessed (instead of accessing members in the parent class).
See Figure 1. This code outputs "Hey! I am Son." Because when PHP calls getSalutation, it is an instance of Son, which overwrites the salutation in Father. Come. If the salutation is public, PHP will produce the same result. Overriding a method operates in a similar way. In Son, the call to identify is bound to that method.
Even in subclasses, access mode is weakened from protected to public , dynamic binding will still occur. According to the principle of using access methods, it is impossible to enhance access restrictions on class members. Therefore, changing the access method from public to protected is impossible.
Dynamic binding
<?php
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
//are the same as getSalutation() in the instance of the Son subclass The method is dynamically bound, so calling the getSalutation() method of the Son instance
will call the member salutation and identify() in the Son class, rather than the member salutation and identify() in the parent class.
Private members only exist in them Inside the class where it is located. Unlike public and protected members, PHP simulates static binding. See the example in Figure 2. It outputs "Hello there! I am Father.", even though the subclass overrides the value of the salutation. The script will this- >salutation is bound to the current class Father. Similar principles apply to the private method identify().
Binding and private members
<?php
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 Figure 3. Due to the use of dynamic binding, the version of isAuthorized called in deleteUser can 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: use To put it clearly in one sentence, it is the binding of object types and methods and attributes. 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 the method in the corresponding class. And attributes.
Benefits of dynamic binding
<?php
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 rarer than you think. In general, a good object hierarchy should allow most functionality to be specialized, improved, or changed by subclasses? This is one of the fundamentals of object-oriented programming. Private methods or variables are necessary 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.