Php 为什么子级可以重写并访问其父级私有方法?
我习惯于在PHP类中将方法设置为受保护的。但是玩Php 为什么子级可以重写并访问其父级私有方法?,php,oop,overriding,visibility,private-methods,Php,Oop,Overriding,Visibility,Private Methods,我习惯于在PHP类中将方法设置为受保护的。但是玩private我开始怀疑了 我知道这可能是重复的,但我无法从我读到的答案中找到清晰的答案。 检查了测试结果,但我的测试结果仍然与测试结果不一致(见下文) 尤其是在PHP上下文中,当扩展同一类型类时,public和private方法之间的“纠缠”并不经常被解释 例如: <?php class A { private function ab() { echo 'test'.PHP_EOL; } public function t
private
我开始怀疑了
我知道这可能是重复的,但我无法从我读到的答案中找到清晰的答案。
检查了测试结果,但我的测试结果仍然与测试结果不一致(见下文)
尤其是在PHP上下文中,当扩展同一类型类时,public
和private
方法之间的“纠缠”并不经常被解释
例如:
<?php
class A
{
private function ab() { echo 'test'.PHP_EOL; }
public function test() { $this->ab(); }
public function accessprivate($obj) { $obj->ab(); }
}
class B extends A
{
public function ab() { echo 'overridden-public'.PHP_EOL; } // expect notice overriding private parent method
}
$a = new A;
$a2 = new A;
$b = new B;
$a->test(); // expect 'test'
$b->test(); // expect access to B::ab() and print 'overridden-public'
$b->ab(); // expect access to B::ab() and print 'overridden-public'
$a2->accessprivate($a); // expect 'test' since is the same class
$b->accessprivate($a); // expect cannotaccess private of A from class B
主要的一点是,我希望一个私有的
方法是继承的,但是子类不能访问它;因此:
- 我不能将
的可见性更改为ab()
public
- 通过在
中重写B
,我希望ab()
在test()
上调用$this
作为ab()
实例,并打印“overrided public”B
上的$a
中的$a2
可以,因为它们是同一类accessprivate()
上的$a
中的$b
不应该很好,因为它们是不同的类(父类和子类)accessprivate()
- 为什么我错了?我误解了什么
- 这个可见性模型在其他语言上是相同的还是PHP做得不同?在这种情况下,我的期望是否更符合其他语言的可见性模型
ab()
的可见性更改为public
重写实现必须具有相同或更高的可见性,才能不违反。重写实现不公开父实现,因此这里没有基本问题。如果父级的实现是非公共的,那么无论出于何种目的,它都不存在。无论出于何种目的,孩子们都在向类中添加一个新方法,这很好
通过在B
中重写ab()
,我希望test()
在$this
上调用ab()
作为B
实例,并打印“overrided public”
private
方法与声明类“硬绑定”A::test
最好调用Aprivate
A::ab
。这是为了使类内部可以保持私有
。如果一个扩展类在不知情的情况下实现了相同的方法,A
中没有令人惊讶的行为
$a
上的$b
中的accessprivate()
不应该很好,因为它们是不同的类(父类和子类)
它仍然在调用A::accessprivate
,因为B
没有实现任何这样的方法,其工作原理与test
方法和上一段中的解释相同
private
的目的主要是保证没有来自外部或扩展代码的干扰。如果将方法标记为private
,则可以非常确定将调用哪个代码实现(始终是声明类),而不管是否在子类中重写方法。如果你记住这一点,这种行为是意料之中的,不言自明<代码>受保护方法明确允许并期望发生重写,并相应地进行操作。您在问题中显示了预期结果,但没有显示实际结果。添加它们可能会有所帮助。谢谢你的建议,好问题。这确实很奇怪。旁注:如果您创建一个C类并在其上定义public function accessprivate($obj){$obj->ab();}
,则会得到预期的错误。我假设当您执行$obj->ab()
时,php的上下文仍然绑定到A,但我不知道为什么。另一方面注意:您在B
上的公共函数ab()
并没有覆盖任何内容。它正在B
上创建一个全新的方法。(其他语言需要override
关键字。Php缺少该关键字,因此可能会造成混淆。)拥有A::ab()
private因此禁止在B
中调用其父级,因此由于私有访问,您无法在B
中执行parent::ab()
。Mmmh,仍在处理它;但这开始有意义了,谢谢你——尽管如此,这还是很棘手的,因为这看起来像是一种隐含的行为,而我更希望得到通知,以防我做了一些我不允许做的事情(或者没有任何效果,比如我的例子不起作用)。关于这个问题,PHP文档似乎不太清楚。这种行为是否在php.net上的任何地方明确记录/提及?
test test overridden-public test test