也许是一直在路上走得太匆忙,而忽视了道路两旁不起眼但点缀了风景的小花小草。
PHP中父类方法里如何访问子类属性?答案很简单,就是父类、子类里属性的权限修饰符都定义为protected就好了。
写了一小段代码进行实践确认的时候,无意间发现自己有些地方不太确定,遂对public,protected,private这块进行了补习。
下面是我的测试代码:
<?php class P { protected $attr = "CoderZhai"; public function getFields(){ echo get_class($this); return $this->attr; } } class C extends P { protected $attr = "Hello World"; } $obj = new C(); var_dump($obj->getFields());
P | C | |
1 | private | private |
2 | private | protected |
3 | private | public |
4 | protected | private |
5 | protected | protected |
6 | protected | public |
7 | public | private |
8 | public | protected |
9 | public | public |
子类里的属性访问权限必须大于或等于父类里的同名属性的权限
答案:有点特殊的就是父类P里属性为private时,$this指向的是子类C,可是$this->attr却调用的是P类的属性。此问题的具体实践分析过程,请继续看后文。
本文为翟码农个人博客蓝翟红尘里php分类下的原创文章,转载请注明出处:http://www.zhai14.com/blog/how-to-call-the-attributes-in-child-class-from-parent-class-in-php.html
下面是翟码农个人结合实践的理解,如有谬误,还望指正。
首先,让我们来熟悉下权限修饰符的描述。
public 公共的 无论是类里还是类外都可访问 protected 受保护的 protected修饰的成员, 可以在当前类或当前类的上下级具有继承关系的类中访问。 private 私有的 private修饰的成员,只能在其所在的类中访问。
接着在上面测试代码,加上如下一行代码,方便调试观察$this的全部内容。
echo get_class($this); var_dump($this); //查看$this详细内容 return $this->attr;
经测试,当P类attr属性为private时,无论子类C的属性是private\protected\public中哪一个,$this打印出来的都是含有两个属性值的。
object(C)[1] private 'attr' => string 'Hello World' (length=11) private 'attr' (P) => string 'CoderZhai' (length=9)
而当把父类P中attr属性改为protected\public时,子类C的同名属性attr赋值则会造成覆写,从而始终只会有一个属性,且属性值是子类C中给予的那个值。当父类P中attr属性为protected,子类C中attr属性为public时,$this打印结果如下:
object(C)[1] public 'attr' => string 'Hello World' (length=11)
由此可见:
当父类中属性为private时,继承于该父类的子类,创建的同名属性,无论什么权限修饰符,都相当于新建的属性,否则就是对父类属性的覆写(override)
对于C类只有一个属性的时候,$this->attr获取的结果毫无疑问。
现在就是当$this指向对象打印出来有两个属性时,即父类属性attr为private的时候,经过实践证明,此时无论$this指向哪个子类,$this->attr调用的都是父类P里的private attr属性。
如果一定要给一个理由,那就是“在哪个类里调用,哪个类的属性就优先”吧,这样子也方便记忆。
记忆诀窍:就近原则,代码在哪个类就优先调用哪个类的属性
不信?那就将getFields方法挪到子类C里面去,你们自己试试看吧。