简体   繁体   English

Php,“只读”可以替换受保护的获取者吗?

[英]Php, can "readonly" replace protected get-ters?

before Php 8.1 we could wrote that:在 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();
    }
}

so getThing() was to get the inner thing object. It could have been written like that:所以getThing()是为了得到里面的thing object。它可以这样写:

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;
    }
}

it's shorter, does the same, but not $thing isn't really protected, it can be read and modified (the first example at least prevented from modifing).它更短,功能相同,但$thing并没有真正受到保护,它可以被读取和修改(第一个示例至少可以防止修改)。 But here comes the readonly modifier:但是这里出现了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;
    }
}

I think this is a serious game changer, makes a lot of getters futile.我认为这是一个严重的游戏规则改变者,让很多 getters 变得徒劳。 Of course it looks you're reaching a tag variable, but still acts like a method, once it was written (in constructor) and now no longer possible to overwrite.当然看起来你正在访问一个标记变量,但它仍然像一个方法一样,一旦它被写入(在构造函数中)并且现在不再可能被覆盖。

So, can "readonly" replace protected get-ters?那么,“readonly”能否取代受保护的 getter 呢?

You're almost there.你快到 The readonly modifier doesn't add any visibility, so you still need to declare the property protected : 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;
    }
}

This will then work for your specific use case .这将适用于您的特定用例 The RFC where the feature was proposed used an example of a public getter being replaced by a public readonly property, which is exactly the same principle: the property can now have the visibility that the getter used to have.提出该功能的 RFC使用了一个公共getter 被公共readonly属性替换的示例,这与原则完全相同:该属性现在可以具有 getter 曾经具有的可见性。

It's important to note that this is not a universal replacement for getters though - in the original code, the base class could write to the property as many times as it liked, but the readonly keyword means "write only once".重要的是要注意,尽管这不是getter 的通用替代品 - 在原始代码中,基数 class可以根据需要多次写入该属性,但readonly关键字表示“只写一次”。 For instance, you might have a counter that is incremented by a particular method in the base class, and want child classes to read it but not write it:例如,您可能有一个计数器,该计数器由基 class 中的特定方法递增,并且希望子类读取它但不写入它:

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();
        // ...
    }
}

Here, readonly is not useful, because it would forbid the $this->counter++ statement in the base class. There is currently a proposal for "asymmetric visibility" , which would cater for this use case - you would be able to say that the variable was "private for writing, but protected for reading".在这里, readonly没有用,因为它会禁止 base class 中的$this->counter++语句。目前有一个针对“不对称可见性”的提议,它可以满足这种用例 - 你可以说变量是“私有的,但受保护的”。 If this passes, the earliest it will be introduced is in PHP 8.3, at the end of 2023.如果通过,最早将在 PHP 8.3 中引入,即 2023 年底。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM