Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 为什么子级可以重写并访问其父级私有方法?_Php_Oop_Overriding_Visibility_Private Methods - Fatal编程技术网

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

我习惯于在PHP类中将方法设置为受保护的。但是玩
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()
    作为
    B
    实例,并打印“overrided public”
  • $a
    上的
    $a2
    中的
    accessprivate()
    可以,因为它们是同一类
  • $a
    上的
    $b
    中的
    accessprivate()
    不应该很好,因为它们是不同的类(父类和子类)
因此,问题是:

  • 为什么我错了?我误解了什么
  • 这个可见性模型在其他语言上是相同的还是PHP做得不同?在这种情况下,我的期望是否更符合其他语言的可见性模型
我不能将
ab()
的可见性更改为
public

重写实现必须具有相同或更高的可见性,才能不违反。重写实现不公开父实现,因此这里没有基本问题。如果父级的实现是非公共的,那么无论出于何种目的,它都不存在。无论出于何种目的,孩子们都在向类中添加一个新方法,这很好

通过在
B
中重写
ab()
,我希望
test()
$this
上调用
ab()
作为
B
实例,并打印“overrided public”

private
方法与声明类“硬绑定”
A::test
最好调用A
private
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