如果你对面向对象编程不熟悉,你可能想知道用private成员的目的是什么. 你可以回忆一下封装和耦合的想法,这在本章开头我们有讨论过. Private成员有助于封装数据. 他们可以隐藏在一个类内部而不被类外部的代码接触到. 同时他们还有助于实现松散的耦合. 如果数据结构外的代码不能直接访问内部属性,那么就不会产生一个隐性的关联性.
当然,大部分private属性仍然可以被外部代码共享. 解决方法是用一对public方法,一个是get(获取属性的值),另一个是set(设置属性的值). 构造函数也接受属性的初始值. 这使得成员间的交流通过一个狭窄的,经过良好限定的接口来进行. 这也提供改变传递给方法的值的机会. 注意在例子6.8中,构造函数如何强制使price成为一个float数(floadval()).
Protected(受保护的) 成员能被同个类中的所有方法和继承出的类的中所有方法访问到. Public属性有违封装的精神,因为它们允许子类依赖于一个特定的属性来书写.protected方法则不会带来这方面的担忧.一个使用 protected方法的子类需要很清楚它的父类的结构才行.
注意Widget现在有一个叫作getName的protected方法. 如果Widget的实例试图调用protected方法将会出错: $w1->getName()产生了一个错误. 但子类Thing中的getName方法可以调用这个protected方法.当然对于证明Widget::getName方法是protected,这个例子显得过于简单. 在实际情况下,使用protected方法要依赖于对对象的内部结构的理解.
以下为引用的内容: public function __construct($name, $price) //checks if two widgets are the same protected function getName() class Thing extends Widget public function setColor($color) public function getColor() public function getName() $w1 = new Widget('Cog', 5.00); //TRUE (still!) 结果仍然为真 //print Cog 输出 Cog |
一个子类可能改变通过覆写父类方法来改变方法的访问方式,尽管如此,仍然有一些限制. 如果你覆写了一个public类成员,他子类中必须保持public. 如果你覆写了一个protected成员,它可保持protected或变成public.Private成员仍然只在当前类中可见. 声明一个与父类的private成员同名的成员将简单地在当前类中建立一个与原来不同的成员. 因此,在技术上你不能覆写一个private成员.
Final关键字是限制访问成员方法的另一个方法. 子类不能覆写父类中标识为final的方法. Final关键字不能用于属性.