PHP中受保护的函数


Protected functions in PHP

这似乎很简单,我相信它是,我只是不明白。

我明白PHP中受保护的属性只能在类本身和继承的类中访问。下面是我到目前为止的代码:

class q {
    public $publicQ = "This is a public property";
    protected $protectedQ = "This is a proected property";
    public function displayProtected() {
        echo $this->protectedQ;
    }
}
$q = new q;
echo $q->publicQ; #prints "This is a public property"
echo $q->protectedQ; #nothing
$q->displayProtected();

我已经阅读了文档,看了其他关于SO的答案,这个概念只是没有点击我。受保护的属性实际上是做什么的,我们为什么要使用它们,为什么我的例子不起作用?

把你的公共属性和方法看作是你向外界公开的API,把私有/受保护的属性和方法看作是你的类的"内部工作",外部世界不仅不应该关心它们,而且也不应该干扰它们。

这里有一个必要的坏车类比:

Car类中公开的方法可以是driveForward()driveBackwards()。它们都将使用一种称为transmitTheDriveToTheWheels()的方法,但它不应该涉及汽车的用户并且不应该被他们访问,因此您将通过将其设置为私有来"隐藏"它。

您的汽车将具有engine属性。你肯定不希望有人能通过$car->engine = $kitty;把引擎换成一只可爱的小猫,所以你也会把引擎设成私人的。

最后,您的汽车将具有mileage属性。您希望用户能够读取里程,但不能修改它。因此,您将mileage设置为私有,并公开一个公共getMileage()方法。

现在,你是想使用private还是protected来封装类的"内部"内容,取决于你是否希望类被扩展。

保护字段可以继承,但不能像echo $q->protectedQ;那样显示私有字段既不能显示也不能继承。

受保护的函数使你的类更灵活。

考虑一个必须在某处加载一些数据的类。它有一个默认实现,从文件中读取数据。如果您想使用同一个类,但是想改变它获取数据的方式,您可以创建一个子类并覆盖getData()函数。

您使用受保护/私有方法来包含功能,以使您的代码更易于阅读,并防止在您的公共方法中重复相同的功能。

设置属性为protected可以防止对象被外部修改,除非你通过setter提供访问权限。

你可以更好地控制你的对象如何被使用

与公共方法的唯一真正区别是,正如您已经发现的那样,受保护的函数只能从类内部或继承树中的另一个类中访问。

当不打算从类外使用函数时,不要将其声明为受保护函数。这是一种语言特性,纯粹是为了让代码更容易理解(更容易阅读),更不容易受到bug和误用的影响。没有什么(以功能的形式)是你不能只用公共方法完成的。

如果你与他人共享你的代码或者它是某种库,它是非常有用的。

对于PHP来说,使用PHP的魔法getter和setter函数有一个特别有用的情况(http://www.php.net/manual/en/language.oop5.overloading.php#object.set)。

public $a = '1';
protected $b = '2';
public function __get($name) {
    return $this->{$name}.' (protected)';
}
$obj->a; //1
$obj->b; //2 (protected)

作为一个例子,你可以"保护"你的变量,用魔术函数捕获调用。如果您已经发布了一个带有变量的类,并且稍后决定在返回变量之前在类中进行一些内部预处理,那么它将非常有用。