gpt4 book ai didi

php - 为什么 child 可以覆盖并访问其父私有(private)方法?

转载 作者:可可西里 更新时间:2023-10-31 23:00:35 29 4
gpt4 key购买 nike

我习惯于将方法作为 protected 放在我的 PHP 类中。但是玩 private 我开始怀疑了。

我知道它可能是重复的,但我无法从我读过的 SO-answers 中找到清晰的答案。检查了 documentationSO answers但我的测试仍然与那里所说的不一致(见下文)。

尤其是在 PHP 上下文中扩展相同类型类时,publicprivate 方法之间的那种“纠结”并不经常被解释。

例如:

<?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() 调用 ab()$this 上作为 B 实例,并打印“overridden-public”
  • accessprivate() from $a2 on $a 没问题,因为它们是同一个类
  • accessprivate() from $b on $a 不应该没问题,因为它们是不同的类(父类和子类)

所以问题是:

  • 为什么我错了?我误解了什么?
  • 这种可见性模型在其他语言上是否相同,或者 PHP 的做法有所不同?在这种情况下,我的期望是否更符合其他语言的可见性模型?

最佳答案

I shouldn't be able to change the visibility of ab() to public

覆盖实现必须具有相同的或更高可见性才能不违反 LSP .覆盖实现不会公开父实现,因此这里没有基本问题。如果父级的实现是非公开的,那么就所有意图和目的而言,它都不存在。出于所有意图和目的, child 正在向类中添加一个新方法,这很好。

with the override of ab() in B I would expect test() to call ab() on $this as B instance, and get printed "overridden-public"

private 方法“硬绑定(bind)”到声明类。 A::test 将优先调用 private A::ab。这是为了让类内部可以保持私有(private)。如果扩展类在不知不觉中实现了相同的方法,A 中的行为就不足为奇了。

accessprivate() from $b on $a should NOT be fine because they are different classes (parent & child)

它仍在调用 A::accessprivate 因为 B 没有实现任何这样的方法,它与 test 方法的工作方式相同以及上一段的解释。

private 的目的主要是为了保证不受外部或扩展代码的干扰。如果您将方法标记为 private,您可以非常确定将调用哪个代码实现(始终是声明类),而不管方法是否在子级中被覆盖。如果您牢记这一点,那么这种行为是很正常的并且是不言自明的。 protected 方法明确允许并期望覆盖发生并相应地运行。

关于php - 为什么 child 可以覆盖并访问其父私有(private)方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57326840/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com