Last week, I coded the following at home. I felt it necessary to say some knowledge required for the interview according to the previous text. (this may be the reason why I stay at home, this may be the reason why I don't have Nan friends, this may be..... Woo!)
What is object cloning?
For objects, PHP uses reference passing, that is, the assignment operation between objects only assigns the value of a reference, not the content of the whole object. The following is an example to illustrate the problems of reference passing:
<?php class My_Class { public $color; } $obj1 = new My_Class (); $obj1->color = "Red"; $obj2 = $obj1; $obj2->color ="Blue"; //The value of $obj1 - > color will also become "Blue" ?>
Because PHP uses reference passing, after executing $obj2 = $obj1, $obj1 and $obj2 point to the same memory area (their relationship in memory is shown in the figure below), and the modification of any object attribute is also visible to another object.
In many cases, you want to copy the same but independent object from an object. PHP provides the clone keyword to copy objects. As shown in the following example:
<?php class My_Class { public $color; } $obj1 = new My_Class (); $obj1->color = "Red"; $obj2 = clone $obj1; $obj2->color ="Blue"; //At this time, the value of $obj1 - > color is still "Red" ?>
$obj2 = clone $obj1 copies the entire memory space of obj1 and stores it in the new memory space, and lets obj2 point to the new memory space. After cloning through clone, their relationship in memory is shown in the following figure.
At this time, the modification of obj2 is invisible to obj1 because they are two independent objects.
When learning C + +, there are the concepts of deep copy and shallow copy. Obviously, PHP also has the same problem. The object cloned through the clone keyword is only a shallow copy of the object. This method can work normally when there are no reference variables in the object, but there will be problems with this copy method when there are reference variables in the object,
The following is an example:
<?php class My_Class { public $color; } $c ="Red"; $obj1 = new My_Class (); $obj1->color =&$c; //Reference passing is used here $obj2 = clone $obj1; //Clone a new object $obj2->color="Blue"; //At this time, the value of $obj1 - > color also becomes "Blue" ?>
In this case, the relationship between the two objects in memory is shown in the following figure.
As can be seen from the above figure, although the objects pointed to by obj1 and obj2 occupy independent memory space, the object's attribute color still points to the same storage space. Therefore, when the value of obj2 - > color is modified, it means that the value of C is modified. Obviously, this modification is also visible to obj1. This is a very typical example of a shallow copy. In order to make the two objects completely independent, you need to make a deep copy of the object. So how to implement it? PHP provides something similar to__ clone method (similar to C + + copy constructor). Copy the attributes requiring deep copy in this method:
Examples of use are as follows:
<?php class My_Class { public $color; public function __clone() { $this->color = clone $this->color; } } $c ="Red"; $obj1 = new My_Class (); $obj1->color =&$c; $obj2 = clone $obj1; $obj2->color="Blue"; //At this time, the value of $obj1 - > color is still "Red" ?>
After deep copy, their relationship in memory is shown in Figure 1-4.
Through in__ In the clone method, copy the reference variable color of the object, so that obj1 and obj2 completely occupy two independent storage spaces, and the modification of obj2 is not visible to obj1.
What is the difference between this, self and parent?
The three keywords this, self and parent are easy to understand literally. They refer to this, yourself and father respectively. Among them, this refers to the pointer to the current object (temporarily described by the pointer in C language), self refers to the pointer to the current class, and parent refers to the pointer to the parent class.
The following will specifically analyze these three keywords.
##this keyword## <?php class UserName { private $name; // Define member properties function __construct($name) { $this->name = $name; // The this pointer has been used here } // Destructor function __destruct() { } // Print user name member function function printName() { print ($this->name." ") ; // this pointer is used again } } // Instantiate object $nameObject = new UserName ( "heiyeluren" ); // Execute printing $nameObject->printName (); // Output: heiyeluren // Second instantiation object $nameObject2 = new UserName ( "PHP5" ); // Execute printing $nameObject2->printName (); // Output: PHP5 ?>
In the above example, this pointer is used in line 5 and line 12 respectively. Who is this pointing to? In fact, this determines who to point to when instantiating. For example, when instantiating an object for the first time (line 16), this points to the $nameObject object object. When printing on line 12, print ($this - > name) becomes print ($nameObject - > name) and "heiyeluren" is output.
For the second instantiated object, print ($this - > name) becomes print ($nameobject2 - > name), so "PHP5" is output.
Therefore, this is a pointer to the current object instance and does not point to any other object or class.
2. self keyword
To be clear, self refers to the class itself, that is, self does not point to any instantiated object. Generally, self is used to access static variables in the class.
<?php class Counter { // Define attributes, including a static variable private static $firstCount = 0; private $lastCount; // Constructor function __construct() { // Use self to call static variables, and use self to call must use:: (field operation symbol) $this->lastCount = ++ selft::$firstCount; } // Print lastCount value function printLastCount() { print ($this->lastCount) ; } } // Instantiate object $countObject = new Counter (); $countObject->printLastCount (); // Output 1 ?>
In the above example, if a static variable $firstCount is defined in line 4 and the initial value is 0, then this value is called in line 9. It is called by self and connected by the domain operator "::" in the middle. At this time, the static variable $firstCount defined by the class itself is called. It has nothing to do with the instances of the following objects, but related to the class, You cannot use this to reference, you can only use self to reference, because self refers to the class itself and has nothing to do with any object instance.
3. parent keyword
Parent is a pointer to the parent class. It is generally used to call the constructor of the parent class.
<?php // Base class class Animal { // Properties of the base class public $name; // name // Constructor of base class public function __construct($name) { $this->name = $name; } } // Derived class class Person extends Animal // The Person class inherits the Animal class { public $personSex; // Gender public $personAge; // Age // Constructor of inherited class function __construct($personSex, $personAge) { parent::__construct ( "heiyeluren" ); // The constructor of the parent class was called with parent $this->personSex = $personSex; $this->personAge = $personAge; } function printPerson() { print ($this->name . " is " . $this->personSex . ",this year " . $this->personAge) ; } } // Instantiate the Person object $personObject = new Person ( "male", "21" ); // Execute printing $personObject->printPerson (); // Output: heiyeluren is male,this year 21 ?>
In the above example, the member attributes are all public, especially those of the parent class, so that the inherited class can access them through this. Line 18: parent:__ Construct ("heiyeluren") uses parent to call the constructor of the parent class to initialize the parent class. Because the members of the parent class are public, you can directly use this in the inherited class to access the properties inherited from the parent class.
What are the differences and relationships between abstract classes and interfaces?
Abstract class application is defined as follows:
abstract class ClassName{ }
Abstract classes have the following characteristics:
1) Define some methods. The subclass must implement all the abstract methods of the parent class. Only in this way can the subclass be instantiated. Otherwise, the subclass is still an abstract class.
2) Abstract classes cannot be instantiated. Their meaning is to be extended.
3) Abstract methods do not need to implement specific functions, but are completed by subclasses.
4) When the subclass implements the methods of the abstract class, the access control of these methods can be the same as that in the parent class, or they can have higher visibility, but they cannot have lower visibility. For example, if an abstract method is declared protected, the method implemented in the subclass should be declared protected or public, not private.
5) If the abstract method has parameters, the implementation of the subclass must also have the same number of parameters and must match. But there is one exception: a subclass can define an optional parameter (this optional parameter must have a default value). Even if there is no such parameter in the declaration of the parent class abstract method, there is no conflict between the two declarations.
Here is an example to deepen the understanding:
<?php abstract class A{ abstract protected function greet($name); } class B extends A { public function greet($name, $how="Hello ") { echo $how.$name." "; } } $b = new B; $b->greet("James"); $b->greet("James","Good morning "); ?>
The running result of the program is
Hello James Good morning James
When defining abstract classes, you usually need to follow the following rules:
1) As long as a class contains at least one abstract method, it must be declared as an abstract class.
2) Abstract methods cannot contain method bodies.
Interface can specify which methods a class must implement, but there is no need to define the specific contents of these methods. In PHP, the interface is implemented through the interface keyword, which is similar to defining a class. The only difference is that the methods defined in the interface are public, and the methods have no method body. All methods in the interface are public. In addition, constants can be defined in the interface. Interface constants and class constants are used exactly the same, but cannot be overridden by subclasses or sub interfaces. To implement an interface, you can use the keyword implements. The class that implements the interface must implement all the methods defined in the interface. Although PHP does not support multiple inheritance, a class can implement multiple interfaces, and the names of multiple interfaces are separated by commas.
An example of interface usage is given below:
<?php interface Fruit { const MAX_WEIGHT = 3; //static const function setName($name); function getName(); } class Banana implements Fruit { private $name; function getName() { return $this->name; } function setName($_name) { $this->name = $_name; } } $b = new Banana(); //create object $b->setName("Banana"); echo $b->getName(); echo "<br />"; echo Banana::MAX_WEIGHT; //static const ?>
The running result of the program is
Banana
3
Interfaces and abstract classes have the following main differences:
Abstract classes: PHP5 supports abstract classes and abstract methods. Classes defined as abstract cannot be instantiated. If at least one method of any class is declared abstract, the class must be declared abstract. The method defined as abstract only declares its calling method and parameters, and cannot define its specific function implementation. Abstract classes are declared with the keyword abstract.
Interface: you can specify which methods a class must implement, but you do not need to define the specific contents of these methods. In this case, you can define an interface through the interface keyword. The methods declared in the interface cannot have a method body.
Although both of them define abstract methods, there are still great differences between them. The main differences are as follows:
1) The implementation of the interface is realized by the keyword implements, while the abstract class inheritance is realized by using the keyword extends of class inheritance.
2) Interfaces have no data members (constants are allowed), but abstract classes have data members (various types of member variables). Abstract classes can encapsulate data.
3) Interface has no constructor, and abstract classes can have constructors.
4) The methods in the interface are all public types, while the methods in the abstract class can be modified with private, protected or public.
5) A class can implement multiple interfaces at the same time, but only one abstract class can be implemented.
Finally, I made a comprehensive summary: about the basic skills mastered in the interview.