我们通过变量的访问掌握先来复习一下这三种访问掌握符的浸染。
classA{private$private;protected$protected;public$public;publicfunctionsetPrivate($p){$this->private=$p;}publicfunctionsetProtected($p){$this->protected=$p;}publicfunctionsetPublic($p){$this->public=$p;}publicfunctiontestA(){echo$this->private,'===',$this->protected,'===',$this->public,PHP_EOL;}}classBextendsA{publicfunctiontestB(){echo$this->private,'===';echo$this->protected,'===',$this->public,PHP_EOL;}}$a=newA();//$a->private='a-private';//atalerror:UncaughtError:CannotaccessprivatepropertyA::$private$a->setPrivate('a-private');//$a->protected='a-protected';//atalerror:UncaughtError:CannotaccessprotectedpropertyA::$protected$a->setProtected('a-protected');$a->public='c-public';$a->testA();echo"Outsidepublic:".$a->public,PHP_EOL;//echo"Outsideprivate:".$a->private,PHP_EOL;//Fatalerror:UncaughtError:CannotaccessprivatepropertyA::$private//echo"Outsideprotected:".$a->protected,PHP_EOL;//Fatalerror:UncaughtError:CannotaccessprotectedpropertyA::$protected$b=newB();$b->setProtected('b-protected');$b->public='b-public';$b->testB();//没有b-private$b->setPrivate('b-private');$b->testB();//没有b-private
从上述代码中很清晰的可以看出,除了public之外的变量都不能在类外部直接调用或者赋值。以是我们利用setXXX()的public方法来为$private和$protected赋值。这里就涌现了封装的观点了,比如在setPrivate()中我们就可以对通报过来的$p变量进行逻辑判断而决定是否将值赋给$private。
B类继续了A类,以是它可以访问到A类的$public和$protected变量,但是,请把稳,$private变量是无法访问到的。以是纵然调用了setPrivate()方法为$private赋值了,但由于B无法访问,以是依然取不到$private的值。有小伙伴要问了,这种情形不报错?当然不会报错,B类会在自己的范围内查找$private变量,没有定义的话就会天生一个局部的变量并赋值为空。

那么子类要利用$private该当怎么办呢?
classCextendsA{private$private;publicfunctiontestC(){echo$this->private,'===',$this->protected,'===',$this->public,PHP_EOL;}//publicfunctionsetPrivate($p){//$this->private=$p;//}}$c=newC();$c->setProtected('c-protected');$c->public='c-public';$c->setPrivate('c-private');$c->testC();
先不要打开C类setPrivate()方法的注释,你会创造\$private依然是空值。也便是说,定义了同名的$private私有变量并不是对父类的变量覆盖,而是在本类浸染域内新建了一个。父类的setPrivate()方法当然也不能访问子类的private变量,因此,子类也要重写一个setPrivate()方法来为自己的$private变量赋值。
记住一点:private润色的变量或方法仅对当前类开放
对付方法的润色也是一样的效果。
classD{publicfunctiontestD(){$this->show();}privatefunctionshow(){echo'ThisisD',PHP_EOL;}}classEextendsD{privatefunctionshow(){echo'ThisisE',PHP_EOL;}}$e=newE();$e->testD();//ThisisD
子类E调用父类D的testD()方法,testD()方法中调用的是private润色的show()方法,根据上面的原则,它依然调用的是自己D类的show()方法。
总结关于访问掌握的内容还是比较大略的,最紧张的便是private这个润色符的问题须要把稳,其他的实在还是比较好理解的。不过越是大略的东西越是根本,面向工具分开不了这三个大略的访问润色符,它们在当代软件开拓中的份量十足,只有牢牢节制它们才是我们精确的学习之道。
测试代码: https://github.com/zhangyue0503/dev-blog/blob/master/php/201912/source/PHP%E7%B1%BB%E4%B8%AD%E8%AE%BF%E9%97%AE%E6%8E%A7%E5%88%B6%E7%9A%84%E4%B8%80%E4%BA%9BTips.php
参考文档: https://www.php.net/manual/zh/language.oop5.visibility.php#87413 https://www.php.net/manual/zh/language.oop5.visibility.php#110555 https://www.php.net/manual/zh/language.oop5.visibility.php