为什么在扩展受保护的 class 变量并将其标记为私有后得到 "Access Level must be protected or weaker"?
Why do I get an "Access Level must be protected or weaker" after extending a protected class variable and marking it private?
abstract class AbstractController
{
protected $repository;
}
class GraphController extends AbstractController
{
private $repository;
}
我收到这个错误:
Fatal error: Access level to GraphController::$repository must be protected or weaker
为什么?这背后的理论是什么?在某种程度上,当我扩展 class 时,我对 class 属性(即 public)的访问级别可能较弱,这感觉不对,因为我在某种程度上暴露父 class 意味着更受限制的变量...
这是传承的规则。您可以使继承成员的可见性更弱(更可见),但不能将其隐藏得更多。所以你可以让它受到保护,或者 public。理由是你不应该能够从基础 class 中隐藏成员,或者使成员比基础 class 作者预期的更不可见。添加到,是,从中删除,否。
这是对上面关于使成员变量更可见的评论的回应...不一定是对原始问题的回应。
试试 运行 这个片段。你会看到仍然会有一个私有变量潜伏在你的 public var 下同名,这取决于你是通过 base-class 方法还是 derived-class 方法访问它,你会得到不同的结果,因为它们是两个不同的实例值。
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# 也是如此。
所以我想从这一切中得出的结论是,尝试更改派生 classes 中基 class instance/members 变量的可见性并不是一个好主意。
abstract class AbstractController
{
protected $repository;
}
class GraphController extends AbstractController
{
private $repository;
}
我收到这个错误:
Fatal error: Access level to GraphController::$repository must be protected or weaker
为什么?这背后的理论是什么?在某种程度上,当我扩展 class 时,我对 class 属性(即 public)的访问级别可能较弱,这感觉不对,因为我在某种程度上暴露父 class 意味着更受限制的变量...
这是传承的规则。您可以使继承成员的可见性更弱(更可见),但不能将其隐藏得更多。所以你可以让它受到保护,或者 public。理由是你不应该能够从基础 class 中隐藏成员,或者使成员比基础 class 作者预期的更不可见。添加到,是,从中删除,否。
这是对上面关于使成员变量更可见的评论的回应...不一定是对原始问题的回应。
试试 运行 这个片段。你会看到仍然会有一个私有变量潜伏在你的 public var 下同名,这取决于你是通过 base-class 方法还是 derived-class 方法访问它,你会得到不同的结果,因为它们是两个不同的实例值。
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# 也是如此。
所以我想从这一切中得出的结论是,尝试更改派生 classes 中基 class instance/members 变量的可见性并不是一个好主意。