Why can child override and access its parent private method?(为什么子级可以重写和访问其父私有方法?)
问题描述
我习惯于将方法作为protected
放在我的PHP类中。但玩private
我开始怀疑了。
我知道它可能是复制品,但我从我读到的一般答案中找不到清晰的答案。 已检查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
实例,并打印"Overoverden-Public" accessprivate()
从$a2
开始$a
可以,因为它们是同一个类accessprivate()
从$b
开始$a
应该不行,因为它们是不同的类(父子)
所以问题是:
- 为什么我说错了?我误解了什么?
- 这种可见性模型在其他语言上是相同的,还是PHP的操作方式不同?在这种情况下,我的期望是否更符合其他语言的可见性模型?
推荐答案
我应该无法将
ab()
的可见性更改为public
重写实现必须具有相同的或更高的可见性,才不会违反LSP。覆盖实现不公开父实现,因此这里没有根本的问题。如果父对象的实现是非公共的,那么无论出于何种目的,它都不存在。无论出于何种目的,孩子都是在向类中添加一个新方法,这很好。
通过重写
B
中的ab()
,我希望test()
在$this
上调用ab()
作为B
实例,并输出"Overoverden-Public"
private
方法被"硬绑定"到声明类。A::test
将调用private
A::ab
。这特别是为了使类内部可以保持private
。如果扩展类在不知情的情况下实现了相同的方法,A
中的行为并不奇怪。
accessprivate()
从$b
在$a
开始不应该很好,因为它们是不同的类(父子)
它仍在调用A::accessprivate
,因为B
没有实现任何此类方法,其工作原理与test
方法和上一段中的解释相同。
private
的主要目的是保证不受外部或扩展代码的干扰。如果将方法标记为private
,则可以非常确定将调用哪个代码实现(始终是声明类),而不管方法是否在子级中被覆盖。如果你记住这一点,这种行为是意料之中的,也是不言而喻的。protected
方法显式允许并期望重写发生,并相应地执行操作。
这篇关于为什么子级可以重写和访问其父私有方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:为什么子级可以重写和访问其父私有方法?


- PHP - if 语句中的倒序 2021-01-01
- 如何从数据库中获取数据以在 laravel 中查看页面? 2022-01-01
- 如何使用 Google API 在团队云端硬盘中创建文件夹? 2022-01-01
- 使用 GD 和 libjpeg 支持编译 PHP 2022-01-01
- openssl_digest vs hash vs hash_hmac?盐与盐的区别HMAC? 2022-01-01
- Oracle 即时客户端 DYLD_LIBRARY_PATH 错误 2022-01-01
- 覆盖 Magento 社区模块控制器的问题 2022-01-01
- Laravel 5:Model.php 中的 MassAssignmentException 2021-01-01
- 如何在 Symfony2 中正确使用 webSockets 2021-01-01
- PHP foreach() 与数组中的数组? 2022-01-01