This article is not suitable for beginners. Those who have a certain understanding of PHP can read it to supplement or review some of the object-oriented features of PHP.
1. What is object-oriented?
Let me introduce a question. Although I know a little bit about it, I still feel that I still can’t solve it. I can only say that everything is regarded as an object. Only in development can you realize what object-oriented is. Just saying it is in vain, but because PHP is mostly used in web development, so it can run well even if it is not object-oriented. When I was doing C++ development before, I designed a functional interface for you. When you see this interface, the first thing you do is to cut it like an artist. Cut it into objects one by one, then determine the relationship between each object, and finally develop it. This idea is everywhere.
What is a class? What is an object?
A class is an abstraction of a set. What set is it? Is a collection of objects with similar properties and operations.
An object is a specific instance of a class.
When I graduate, I may recite it to the interviewer, but now, although my understanding is still as vulgar as the sentences in the book, at least I no longer need to rely on my brain cells to express these two definitions.
Class structure in 2.php
Classes in PHP are also access control characters, and they also have attributes and methods.
class Person { private $name = "PersonName"; public static $gender = "PersonGender"; public function test(){ echo $this->name, '<br />'; } };
The name of the constructor is __construct. I want to emphasize the following points in the constructor:
1. PHP will not automatically call the constructor of your parent class when instantiating a subclass like other languages (C++ or Java). In PHP, you need to manually call the constructor of the parent class, which involves inheritance. , you can take a look at inheritance first.
class Person{ public funciton __construct(){ echo 'Person construct<br />'; } }; class Teacher extends Person{ public function __construct(){ //parent::__construct(); echo 'Teacher construct<br />'; } }; $t1 = new Teacher; //生成Teacher对象
Run results:
Teacher construct
If you want to initialize some data of the parent class when generating a subclass, you need to manually call the constructor of the parent class and just open the comment line.
2. You cannot write two constructors with different parameters in a class.
This involves some regulations in PHP. In other languages, the following writing is correct:
class Person{ public funciton __construct(){ echo 'Person construct<br />'; } public function __construct($param){ echo 'Person with param construct<br />'; } };
However, it is not allowed in PHP. The root cause is that PHP is a weak language type and is not very sensitive to type restrictions. It then provides __call and func_get_args function mechanisms, so it can be implemented in the following way:
class Person{ public function __construct(){ $param = func_get_arg(); //获取参数数据 $param_num = func_num_args(); //获取参数个数 if($param_num == 0){ }else if($param_num == 1){ if(is_array($param[0])){ //... } }else{ //... } } };
3. Destructor
The destructor is a function that is automatically called when the instance object ends. You can write a statement to release the memory to draw a perfect end to the death of the instance. This is the same as the construction. It is necessary when there is an inheritance relationship. Manually call the destructor of the parent class. There is only one destructor in a class.
4. Control access characters
public: Public accessor, this property or method can be accessed within the class, within the subclass, and outside the class.
protected: Protected accessor, this property or method can only be accessed within the class and its subclasses, and cannot be accessed outside the class.
private: Private accessor, which can only be accessed within this class. It is private stuff of this class. It cannot be inherited, cannot be overloaded, and cannot be accessed by anyone.
5. Magic methods __get and __set
The functions of these two methods: an accessor for protected and private property access, which can verify the security and rationality of data received from outside the class.
The __set method receives two parameters, the first is the attribute name, and the second is the new value to be assigned.
The __get method receives one parameter, the attribute name.
1. Public attributes can provide services for modifying attributes outside the class. Therefore, for public attributes, the __get and __set processes will not be followed.
class D{ public $name = 'D name'; protected $gender = 'male'; private $age = 18; public function __set($name, $value){ echo '__set<br />'; //if(in_array($name, ['name', 'gender', 'age'])) $this->$name = $value; } public function __get($name){ echo '__get<br />'; //if(!in_array($name, ['name', 'gender', 'age'])) return NULL; return $this->$name; } };
运行结果:
new D name //name为public属性,不会走get和set __set __get new D gender __set __get new D age
2. We can also add the function of data verification, and verification can be performed by opening the comments.
3. The two methods must have public access, otherwise an error will be prompted. We can think from the functions of these two functions, and it is not difficult to imagine why public access control is needed.
6. Inheritance
Finally, you have the feature that can make your chrysanthemum bloom. Without inheritance, all classes are rubbish. Because of inheritance,... problems are coming in waves... Let Let’s take a closer look at this inheritance feature.
Let’s not talk about inheritance. There is a small example of inheritance at the beginning of the article.
What problems will occur if there is inheritance? Think about it, if B inherits A... It's really unimaginable...
1. Constructor, don’t worry, it has nothing to do with inheritance. It is equivalent to the constructor in two classes, but there is a parent-child relationship anyway. You can’t do things too well. So, as mentioned above, If necessary, you can manually call the constructor of the parent class. You can see the example above.
2. One-way inheritance. Inheritance is one-way. Subclasses can inherit from parent classes, but parent classes cannot inherit features from subclasses. Example:
class A{ public $attr1; public function oper1(){ } }; class B extends A{ public $attr2; public function oper2(){ } }; //子类可以继承父类 $b = new B; $b->oper1(); $b->attr1 = 'attr1 value'; $b->oper2(); $b->attr2 = 'attr2 value'; //父类不能继承子类 $a = new A; $a->oper2();//出错 $a->attr1();//出错
3. Overloading. When it comes to overloading in PHP, it is very awkward, because its overloading is called overwrite in other languages. I am still used to calling this feature overwriting, so you can feel free to use it.
<1>public重载:
class E{ public $attr1 = 'E attr1 value'; public function oper1(){ echo 'E oper1<br />'; echo 'attr1 value = ', $this->attr1, '<br />'; } }; class F extends E{ public $attr1 = 'F attr1 value'; public function oper1(){ //parent::oper1(); echo 'F oper1<br />'; echo 'attr1 value = ', $this->attr1, '<br />'; } }; $f = new F; $f->oper1();
运行结果:
F oper1
attr1 value = F attr1 value
F继承了E并且重写了E的attr1和oper1,因此,在调用oper1时,$this->attr1显示F attr1 value,如果打开注释parent::oper1调用父类的Oper1方法,运行结果如下:
E oper1
attr1 value = F attr1 value //attr1属性已经被子类重写的attr1属性覆盖
F oper1
attr1 value = F attr1 value
可以看出子类重写父类的属性和方法后,会覆盖父类相应的属性和方法。
<2>private重载
class E{ private $attr1 = 'E attr1 value'; public function oper1(){ echo 'E oper1<br />'; echo 'attr1 value = ', $this->attr1, '<br />'; } }; class F extends E{ public $attr1 = 'F attr1 value'; public function oper1(){ parent::oper1(); echo 'F oper1<br />'; echo 'attr1 value = ', $this->attr1, '<br />'; } }; $f = new F; $f->oper1();
E oper1
attr1 value = E attr1 value //父类私有的属性
F oper1
attr1 value = F attr1 value
之前我们说过,private属性和方法子类是继承不了的,这种情况,遵循一个原则:
private属性在那个类里调用的,就显示哪个类里的属性值。
示例中的parent::oper1方法调用的是E类的oper1方法,在E的oper1方法内又调用了$this->attr1,attr1是private并没有被子类继承,因此,调用的就是类E里的attr1属性值。
<3>protected重载与public重载一致
<4>类属性的继承
class G{ public static $attr1 = 'G attr1 value'; public function oper1(){ echo 'G oper1<br />'; echo 'attr1 value = ', self::$attr1, '<br />'; } }; class H extends G{ public static $attr1 = 'H attr1 value'; public function oper1(){ parent::oper1(); echo 'H oper1<br />'; echo 'attr1 value = ', self::$attr1, '<br />'; } }; $h = new H; $h->oper1();
运行结果:
G oper1
attr1 value = G attr1 value
H oper1
attr1 value = H attr1 value
其实不管G类的attr1属性是public还是private,结果都一样。
个人是这么理解的,类属性可以继承,但谈不上重载,那关于子类调用父类的属性也有一规则:
self或者parent只代表本类,因此,根据这一原则可以断定,属性的值一定是本类属性的值,与子类无关。(特殊情况时php的静态延迟加载机制)。
七.静态延迟加载
既然已经提到了静态延迟加载,就趁热打铁讲一下,H和G的例子大家已经看了,那我就是想要在子类中调用父类的东东怎么办?静态延迟加载就是解决这个问题,请看两个示例:
示例1:
还是H和G类的例子
class G{ public static $attr1 = 'G attr1 value'; public function oper1(){ echo 'G oper1<br />'; echo 'attr1 value = ', static::$attr1, '<br />'; } }; class H extends G{ public static $attr1 = 'H attr1 value'; public function oper1(){ parent::oper1(); echo 'H oper1<br />'; echo 'attr1 value = ', self::$attr1, '<br />'; } }; $h = new H; $h->oper1();
G oper1
attr1 value = H attr1 value
H oper1
attr1 value = H attr1 value
上面代码只是将G类里的self::$attr1改写成了static::$attr1,运行结果就不一样了
示例2:
class I { public static function who(){ echo __CLASS__, '<br />'; } public static function test(){ static::who(); } }; class J extends I{ public static function who(){ echo __CLASS__,'<br />'; } };
运行结果:
J
通过这两个例子,可以好好的领悟一下static的静态延迟绑定。
写的有点多,主要是因为一牵扯继承就停不下来....面向对象还有一些只是点,后面有时间再补上吧...谢谢,如若有错误的地方,敬请大家指出,随时更正,谢谢!!