【发布时间】:2019-12-11 02:28:12
【问题描述】:
我习惯将方法作为protected 放在我的PHP 类中。但是玩private 我开始怀疑了。
我知道它可能是重复的,但我无法从我读过的 SO-answers 中找到清晰的答案。 检查了documentation 和SO answers,但我的测试仍然与那里所说的不一致(见下文)。
尤其是在 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
运行结果如下:
test test overridden-public test test
主要的一点是我希望private 方法被继承,但子类无法访问;因此:
- 我应该无法将
ab()的可见性更改为public - 在
B中覆盖ab()我希望test()在$this上调用ab()作为B实例,并打印“overridden-public” -
accessprivate()from$a2on$a很好,因为它们是同一类 -
accessprivate()from$bon$a应该不行,因为它们是不同的类(父母和孩子)
所以问题是:
- 为什么我错了?我误会了什么?
- 这种可见性模型在其他语言上是否相同,或者 PHP 的做法不同?在这种情况下,我的期望是否更适合其他语言的可见性模型?
【问题讨论】:
-
您在问题中显示了预期结果,而不是实际结果。添加它们可能会有所帮助。
-
已添加。谢谢你的建议????
-
好问题。确实很奇葩。旁注:如果您创建一个类 C 并在其上定义
public function accessprivate($obj) { $obj->ab(); },您会得到预期的错误。我假设当您执行$obj->ab()时,php 的上下文仍然绑定到 A,但我不知道为什么。 -
其他旁注:您在
B上的public function ab()没有覆盖任何内容。它在B上创建了一个全新的方法。 (其他语言需要override关键字。Php 缺少此关键字,因此这可能会造成混淆。)拥有A::ab()私有因此禁止在B中调用其父调用,因此由于私有访问,您不能在B内执行parent::ab().
标签: php oop overriding visibility private-methods