为什么子级可以重写和访问其父私有方法? [英] Why can child override and access its parent private method?

查看:0
本文介绍了为什么子级可以重写和访问其父私有方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

我知道它可能是复制品,但我从我读到的一般答案中找不到清晰的答案。 已检查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()$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将调用privateA::ab。这特别是为了使类内部可以保持private。如果扩展类在不知情的情况下实现了相同的方法A中的行为并不奇怪。

accessprivate()$b$a开始不应该很好,因为它们是不同的类(父子)

它仍在调用A::accessprivate,因为B没有实现任何此类方法,其工作原理与test方法和上一段中的解释相同。

private的主要目的是保证不受外部或扩展代码的干扰。如果将方法标记为private,则可以非常确定将调用哪个代码实现(始终是声明类),而不管方法是否在子级中被覆盖。如果你记住这一点,这种行为是意料之中的,也是不言而喻的。protected方法显式允许并期望重写发生,并相应地执行操作。

这篇关于为什么子级可以重写和访问其父私有方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆