PHP,"readonly"可以替换受保护的获取者吗?



在Php 8.1之前我们可以这样写:

abstract class Base
{
private $thing;
public function __construct($thing)
{
$this->thing = $thing;
}
protected function getThing()
{
return $this->thing;
}
}
class Test1 extends Base
{
private function needThing()
{
... $this->getThing();
}
}
class Test2 extends Base
{
private function needThing()
{
... $this->getThing();
}
}

表示getThing()将得到内部的thing对象。它可以这样写:

abstract class Base
{
protected $thing;
public function __construct($thing)
{
$this->thing = $thing;
}
}
class Test1 extends Base
{
private function needThing()
{
... $this->thing;
}
}
class Test2 extends Base
{
private function needThing()
{
... $this->thing;
}
}

它更短,做同样的事情,但不是$thing不是真正的保护,它可以被读取和修改(第一个例子至少防止修改)。但是这里出现了readonly修饰符:

abstract class Base
{
readonly private $thing;
public function __construct($thing)
{
$this->thing = $thing;
}
protected function getThing()
{
return $this->thing;
}
}
class Test1 extends Base
{
private function needThing()
{
... $this->thing;
}
}
class Test2 extends Base
{
private function needThing()
{
... $this->thing;
}
}

我认为这是一个严重的游戏改变者,使许多人徒劳。当然,它看起来是到达一个标签变量,但它仍然像一个方法,一旦它被写入(在构造函数中),现在不再可能覆盖。

所以,可以"readonly"替换受保护的获取器?

你就快成功了readonly修饰符没有给添加任何可见性,所以您仍然需要声明属性protected:

abstract class Base
{
readonly protected $thing;
public function __construct($thing)
{
$this->thing = $thing;
}
}
class Test1 extends Base
{
private function needThing()
{
... $this->thing;
}
}
class Test2 extends Base
{
private function needThing()
{
... $this->thing;
}
}

这将适用于您的特定用例。提出该特性的RFC使用了一个publicreadonly属性替换publicgetter的例子,这是完全相同的原理:该属性现在可以具有getter曾经具有的可见性。

需要注意的是,并不是getter的通用替代品——在原始代码中,基类可以向属性写入任意多次,但是readonly关键字意味着"只写入一次"。例如,您可能有一个计数器,该计数器由基类中的特定方法递增,并且希望子类读取它而不是写入它:
abstract class Base
{
private int $counter = 0;
protected function getCounter(): int {
return $this->counter;
}
public function doSomething(): void {
// ...
$this->counter++;
// ...
}
}
class Test1 extends Base
{
private function needCounter()
{
// ... 
$counter = $this->getCounter();
// ...
}
}

这里,readonly是没有用的,因为它会禁止在基类中使用$this->counter++语句。目前有一个关于"不对称可见性"的建议,它将满足这个用例——您将可以说变量"在写时是私有的,但在读时是受保护的"。如果通过,它最早将在2023年底的PHP 8.3中引入。

相关内容

  • 没有找到相关文章

最新更新