【问题标题】:Why do I get an "Access Level must be protected or weaker" after extending a protected class variable and marking it private?为什么在扩展受保护的类变量并将其标记为私有后,我会得到“访问级别必须受到保护或更弱”?
【发布时间】:2017-12-30 14:27:56
【问题描述】:
abstract class AbstractController
{
    protected $repository;
}

class GraphController extends AbstractController
{
    private $repository;
}

我收到此错误:

致命错误:GraphController::$repository 的访问级别必须受到保护或更弱

为什么?这背后的理论是什么?在某种程度上,当我扩展一个类时,我对类属性(即公共)的访问级别可能较弱,这感觉是错误的,因为我在某种程度上暴露了一个由父类意味着受到更多限制的变量......

【问题讨论】:

    标签: php inheritance access-levels


    【解决方案1】:

    这是对上述评论的回应,这与使成员变量更可见有关......不一定是对原始问题的回应。

    尝试运行这个片段。你会看到在你的公共变量下面仍然会有一个同名的私有变量,并且取决于你是通过基类方法还是派生类方法访问它,你会得到不同的结果,因为它们是两个不同的实例值。

    class baseclass {
        private $hideme;
        public function getit() { return $this->hideme; }
        public function setit($value) { $this->hideme = $value; }
    }
    
    class derived extends baseclass {
        public $hideme;
    }
    
    function doobee(baseclass $obj) {
        echo $obj->getit() . "\n";
    }
    
    $a = new derived();
    $a->hideme = "direct assign";
    $a->setit("accessor assign");
    
    ?><pre><?php
    echo '$a->getit(); // ' . $a->getit() . "\n";
    echo '$a->hideme; // ' . $a->hideme . "\n";
    echo 'doobee($a); // '; doobee($a);
    
    echo 'print_r($a);' . "\n";
    print_r($a);
    ?></pre>
    

    输出:

    $a->getit(); // accessor assign
    $a->hideme; // direct assign
    doobee($a); // accessor assign
    print_r($a);
    derived Object
    (
        [hideme] => direct assign
        [hideme:baseclass:private] => accessor assign
    )
    

    不只是 PHP 有这种行为;例如 C# 也是如此。

    所以我想从这一切中得出的结论是,尝试更改派生类中基类实例/成员变量的可见性并不是一个好主意。

    【讨论】:

      【解决方案2】:

      这是继承的规则。您可以使继承成员的可见性更弱(更明显),但不能将其隐藏得更多。因此,您可以将其设为受保护或公开。理由是您不应该能够从基类中隐藏成员,或者使成员的可见性低于基类作者的预期。添加到,是的,带走,不是。

      【讨论】:

      • 好吧,这是有道理的,尽管我几乎可以采用任何类,扩展它,并使该类的变量公开,从而绕过该类打算拥有的任何封装。不是我会故意这样做,但可以这样做
      • 您可能认为您可以派生基类并使成员变量更加可见,但它不会按照您的想法工作,并且最终会有点混乱。我会在另一个回复中解释。
      猜你喜欢
      • 2016-03-08
      • 2014-11-10
      • 2011-10-06
      • 2019-10-27
      • 2012-06-22
      • 2018-07-16
      • 2011-10-02
      • 2012-01-19
      相关资源
      最近更新 更多