访问修饰符的意义
本文主要讲解为何有些成员变量需要设置成私有的,为什么不能直接设置成public直接在外部访问,以及PHP魔术方法__get()和__set()的使用
先上一段代码好说明问题
1 | class User { |
- 如上,我们觉得好像private改成public也没什么大问题,但是如果有这样一个场景,调用代码中,多处调用了User的salary属性,有写的也有读的,但是有一天,你不想让调用者修改salary了(禁用写),那怎么办?要怎么保证调用者的代码中没有直接修改salary的代码?如果提供了setter,那么只要把setter删掉,一旦调用代码中有没清理干净的对salary进行写入/修改 的代码,那么就会抛出异常。而使用public $salary这种方式的话,改成private后,虽然是可以禁止写了但是连读取也被禁止了。
- 对写入数据的操作/过滤,使用setter和getter,可以统一对写入/读取 进行操作或者过滤,比如要去掉写入数据中的空格,如果使用public,那么要在每个调用处写上trim(),但是我们无法保证每处都写上trim了。如果用setter,那么我们可以在setter中写一次trim即可,而且也保证对每次写入都会进行过滤,不会有遗漏。
注意:由于 __get() 和 __set() 是在遍历所有成员变量,找不到匹配的成员变量时才被调用。因此,其效率是低于直接访问成员变量的形式。在一些表示数据结构、数据集合等简单情况下,且不需读写控制等, 可以考虑使用成员变量作为属性直接访问,这样可以提高一点效率。
另外一个提高效率的技巧就是:使用 $k1 = $obj->getK1() 来代替 $k1 = $obj->K1 , 用 $obj->setK1($value) 来代替 $obj->K1 = $value 。 这在功能上是完全一样的效果,但是避免了使用 __get() 和 __set() ,相当于绕过了遍历的过程。
这里还要区分,在类里成员变量和属性的区别。成员变量和属性的区别与联系在于:
- 成员变量是一个“内”概念,反映的是就类的结构构成而言的该你那。属性是一个“外”概念,反映的是类的功能逻辑意义而言的概念。
- 成员变量没有读写权限控制,而属性可以指定为只读或只写,或可读可写。
- 成员变量不对读出作任何后处理,不对写入作任何预处理,而属性则可以。
- public成员变量可以视为一个可读可写、没有任何预处理或后处理的属性。 而private成员变量由于外部不可见,与属性“外”的特性不相符,所以不能视为属性。
- 虽然大多数情况下,属性会由某个或某些成员变量来表示,但属性与成员变量没有必然的对应关系, 比如与非门的 output 属性,就没有一个所谓的 $output 成员变量与之对应。
为了更形象,我们看个例子
1 | class NotAndGate { |
上面的代码中,与非门类有两个成员变量, $_k1 和 $_k2 。但是有3个属性,表示2个输入的 key1 和 key2 ,以及表示输出的 output 。
由于我们知道,属性一般是通过$obj->property方式来访问的,但是这里根本没有output这个成员变量呀?那还怎么访问呢?
没错,这时候就要靠我们的魔术方法__get()来配合getter了,上__get()的代码:
1 | public function __get($name) { |
欢迎转载但请附上链接,谢谢。
参考:http://www.digpage.com/property.html
如有什么错误,欢迎提出、讨论,大家共同进步 _