具有以下类层次结构:
class TheParent{
public function parse(){
$this->validate();
}
}
class TheChild extends TheParent{
private function validate(){
echo 'Valid!!';
}
}
$child= new TheChild();
$child->parse();
这个步骤的顺序是什么?
问题是当我运行该代码时出现以下错误:
Fatal error: Call to private method TheChild::validate() from context 'TheParent' on line 4
由于TheChild
继承的TheParent
不应该$this
parse()
中的$child
,而是validate()
的实例,所以parse()
将validate()
对protected
可见?
注意:
在做了一些研究之后,我发现这个问题的解决方案要么根据PHP手册中的this comment制作abstract protected
函数validate()
,尽管我不完全理解为什么它正在工作在这种情况下。
第二个解决方案是在父级中创建protected
方法{{1}},并将其作为子级{{1}}方法覆盖在子级(这将是多余的)第一个解决方案中可以从父母那里访问吗?!!
有人可以解释继承在这种情况下的工作原理吗?
答案 0 :(得分:15)
其他海报已经指出,需要保护这些方法以便访问它们。
我认为你应该在代码中再改变一件事。您的基类parent
依赖于子类中定义的方法。这是糟糕的编程。像这样更改你的代码:
abstract class TheParent{
public function parse(){
$this->validate();
}
abstract function validate();
}
class TheChild extends TheParent{
protected function validate(){
echo 'Valid!!';
}
}
$child= new TheChild();
$child->parse();
创建一个抽象函数可确保子类绝对具有函数validate
,因为必须实现抽象类的所有抽象函数才能继承这样一个班级
答案 1 :(得分:4)
你对遗产的看法是正确的,而不是可见性。
受保护可以由类使用,并且继承和父类,private只能在它定义的实际类中使用。
答案 2 :(得分:2)
私人只能通过定义父类和子类的类来访问。
使用protected而不是:
class TheParent{
public function parse(){
$this->validate();
}
}
class TheChild extends TheParent{
protected function validate(){
echo 'Valid!!';
}
}
$child= new TheChild();
$child->parse();
答案 3 :(得分:0)
来自PHP DOC
相同类型的对象可以访问彼此私有和受保护的成员,即使它们不是同一个实例。这是因为在这些对象内部已经知道实现特定的细节。
私人只能通过class which defines
或Same object type
示例
class TheChild {
public function parse(TheChild $new) {
$this->validate();
$new->validate(); // <------------ Calling Private Method of $new
}
private function validate() {
echo 'Valid!!';
}
}
$child = new TheChild();
$child->parse(new TheChild());
输出
有效!!有效!!