搜索
首页后端开发php教程一个关于父类方法访问子类对象中的公有属性的问题

如图所示:


回复讨论(解决方案)

private $_name = '韩'; 是父类私有属性,所以子类不能修改其值。
showName是父类方法,所以把父类的$_name = '韩'; 输出。

把private 改为 protected 或 public就可以了。

或者在Kang类重写一下showName方法。

<?phpclass Han{    public $p1 = 1;    private $_name = '韩';    public function showName(){        echo '<br>p1='.$this->p1.',_name='.$this->_name;        echo '<br>类:'.get_class($this).',方法:'.__METHOD__;    }}class Kang extends Han{    public $p1 = 10;    public $_name = '康';    public function showName(){        echo '<br>p1='.$this->p1.',_name='.$this->_name;        echo '<br>类:'.get_class($this).',方法:'.__METHOD__;    }}echo '<meta http-equiv="content-type" content="text/html; charset=utf-8">';$o = new Kang;var_dump($o);echo '<br>p1='.$o->p1.',_name='.$o->_name;$o->showName();?>

private $_name = '韩'; 是父类私有属性,所以子类不能修改其值。
showName是父类方法,所以把父类的$_name = '韩'; 输出。

把private 改为 protected 或 public就可以了。



我要的是“解释”,就是为什么这里输出的是“韩”而不是“康”?不是为了要输出这个“康”这个属性数据。
你说的这个“showName是父类方法,所以把父类的$_name = '韩'; 输出。”,略算解释,但我还是想要更深入的说法。
我知道showName是父类方法,输出的"韩“是父类的私有属性值。
我的意思是,"$o"这个对象,也就是showName中的$this,明明是有公有属性_name, 和p1,为什么在其中p1可以输出10,而_name输出的是私有的那个,而不是公有的那个?(我们可以观察到,$o也就是$this中有2个_name,一个公有,一个私有)。
明明在外面,$o->_name是可以输出”康“的,而showName中的$this也就是这个$o, 则在这里面,怎么$o->_name输出的就是”韩“了呢?

谢谢 fdipzone!

因为私有的是不可侵犯的,所以私有的属性不能被覆盖

因为私有的是不可侵犯的,所以私有的属性不能被覆盖


我明白该父类的属性并没有被覆盖。倒是引出了另一个问题,那就是,我们var_dump($o),可以看到有2个_name属性,一个私有,一个公有,则该私有的该如何看待的问题。因为按通常说法,私有属性是不能继承的,则子类中定义的_name作为公有属性,并没有覆盖父类的同名属性。相反,应该看作是子类的”全新属性“。则在子类对象$o中看到的这个私有$_name,该做如何解释呢?

不过我的困惑仍然是这样:$o->_name作为公有的属性明明是可以直接访问的(输出”康“),但在其继承下来的方法showName中,$this->_name为什么就不是这个公有的_name,而是私有的_name呢?这里,我代码中给出的$o和$this毫无疑问肯定是“同一对象”。

明明在外面,$o->_name是可以输出”康“的,而showName中的$this也就是这个$o, 则在这里面,怎么$o->_name输出的就是”韩“了呢?

showName是父类的方法,所以是调用父类的属性_name。
而$o->_name是调用子类对象的_name属性,所以会读取Kang的_name

而把private $_name改为 public $_name;,则子类实例化时,会用子类的_name覆盖父类的_name,即父类的_name等于子类的_name。

而在Kang中添加showName,这样会覆盖父类的showName方法,显示的就是子类的_name。

var_dump 反映的是 kang 的内部情况,自然私有属性也是会展示出来

showName 方法是 Han 定义的,他的 $this 自然是 Han,由于私有属性 _name 没有被覆盖所以能被他访问到
而外部只能访问到 Kang 定义的公有属性 _name

如果你在 Kang 中也定义一个 showName 那么 私有属性 _name 在 Kang 中就访问不到了

var_dump 反映的是 kang 的内部情况,自然私有属性也是会展示出来

showName 方法是 Han 定义的,他的 $this 自然是 Han,由于私有属性 _name 没有被覆盖所以能被他访问到
而外部只能访问到 Kang 定义的公有属性 _name

如果你在 Kang 中也定义一个 showName 那么 私有属性 _name 在 Kang 中就访问不到了



其他的我都能认可,能理解,但关于这一句“showName 方法是 Han 定义的,他的 $this 自然是 Han”,我实际测试其实是,$this和$o是“全等”的,实际上就是一个对象($o)。
另外,从var_dump($o)看到的对象$o的内部情况,确实可以看到它有两个_name属性,一个是公有的,一个是私有的。或者,理论上,在showName中,这两个其实都能访问到。比如,把Han类中的私有属性_name注释掉,就可以访问其子类的公有的_name属性了。
实际上,我的问题,就在这里:为什么这里输出的是私有的那个_name,而不是共有的那个_name。
我想要知道的是一个理论上的解释,或原理上的解释,至于现象,或单纯的解释为“因为showName是Han类定义的,所以Han类中的私有属性可以被其访问到”,我是知道的。
这里可以肯定的是,$o对象有两个_name属性,一个来自Han类的私有,一个来自Kang类的公有,showName()方法对这两个都可以访问到。我想到的一个可能的解释是:方法优先访问其所在类中定义的”同属一类“的属性。但实际上,这个解释是我想象出来的,我没有在哪里见过。所以,我就想要知道,一个更深入的有关此现象的解释。
ok?谢谢各位!

你把 echo '
类:'.get_class($this).',方法:'.__METHOD__;
改成 echo '
类:'. __CLASS__ .',方法:'.__METHOD__;
就可以从结果中看出了

p1=10,_name=康
p1=10,_name=韩
类: Han,方法:Han::showName

虽然 Kong 了继承了 Han 的方法 showName (__METHOD__ 为 Han::showName)
但他依然工作在 Han 类中,那么 $this->_name 就是 Han::_name 并且永远都是
如果 Han::_name 不是私有的,那么 Kong::_name 将会覆盖 Han::_name
但并不是说 $this->_name 访问的是 Kong::_name,而实际上依然是 Han::_name,只不过两个的值相同而已

嗯,9楼xuzuning版主这次的解释已经接近我想要的了,hoho。

我再就细节探讨探讨。

你让我把get_class($this),替换成__CLASS__,然后得到的是”Han”这个类名。但这只能说明showName方法所在类,因为__CLASS__永远指的是其所在方法的所属类。而并不能说明在showName方法中,$this->_name为什么是"韩",而不是“康”。而且,在这里,$this它就是“kang”类对象??不过我突然想到,它确实也是“Han”类对象,因为Kang是Han的子类,子类对象自然一定是父类的对象。由此解释的话,则$this->_name确实是应该输出Han::_name的值了。
不过你后面的解释,showName方法“依然工作在 Han 类中,那么 $this->_name 就是 Han::_name 并且永远都是”,是否过于绝对呢?比如,如果Han中没有_name这个属性,则$this->_name不就访问了Kang类对象$o(也就是这里的$this)的_name了么。但你后面的解释说,如果Han::_name不是私有的,则会被子类覆盖,然后此时访问的$this->_name将仍然是Han::_name,对我来说倒是挺新鲜的,受益匪浅。

如果Han::_name不是私有的,则会被子类覆盖,然后此时访问的$this->_name将仍然是Han::_name,是这样的。
是两个类的值,只是如果不是私有,父类的值与子类一样。

如果父类有私有的属性,那么父类的方法只为父类的私有属性服务。 

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
解释负载平衡如何影响会话管理以及如何解决。解释负载平衡如何影响会话管理以及如何解决。Apr 29, 2025 am 12:42 AM

负载均衡会影响会话管理,但可以通过会话复制、会话粘性和集中式会话存储解决。1.会话复制在服务器间复制会话数据。2.会话粘性将用户请求定向到同一服务器。3.集中式会话存储使用独立服务器如Redis存储会话数据,确保数据共享。

说明会话锁定的概念。说明会话锁定的概念。Apr 29, 2025 am 12:39 AM

Sessionlockingisatechniqueusedtoensureauser'ssessionremainsexclusivetooneuseratatime.Itiscrucialforpreventingdatacorruptionandsecuritybreachesinmulti-userapplications.Sessionlockingisimplementedusingserver-sidelockingmechanisms,suchasReentrantLockinJ

有其他PHP会议的选择吗?有其他PHP会议的选择吗?Apr 29, 2025 am 12:36 AM

PHP会话的替代方案包括Cookies、Token-basedAuthentication、Database-basedSessions和Redis/Memcached。1.Cookies通过在客户端存储数据来管理会话,简单但安全性低。2.Token-basedAuthentication使用令牌验证用户,安全性高但需额外逻辑。3.Database-basedSessions将数据存储在数据库中,扩展性好但可能影响性能。4.Redis/Memcached使用分布式缓存提高性能和扩展性,但需额外配

在PHP的上下文中定义'会话劫持”一词。在PHP的上下文中定义'会话劫持”一词。Apr 29, 2025 am 12:33 AM

Sessionhijacking是指攻击者通过获取用户的sessionID来冒充用户。防范方法包括:1)使用HTTPS加密通信;2)验证sessionID的来源;3)使用安全的sessionID生成算法;4)定期更新sessionID。

PHP的完整形式是什么?PHP的完整形式是什么?Apr 28, 2025 pm 04:58 PM

文章讨论了PHP,详细介绍了其完整形式,在We​​b开发中的主要用途,与Python和Java的比较以及对初学者的学习便利性。

PHP如何处理形式数据?PHP如何处理形式数据?Apr 28, 2025 pm 04:57 PM

PHP使用$ \ _ post和$ \ _获取超级全局的php处理数据,并通过验证,消毒和安全数据库交互确保安全性。

PHP和ASP.NET有什么区别?PHP和ASP.NET有什么区别?Apr 28, 2025 pm 04:56 PM

本文比较了PHP和ASP.NET,重点是它们对大规模Web应用程序,性能差异和安全功能的适用性。两者对于大型项目都是可行的,但是PHP是开源和无关的,而ASP.NET,

PHP是对病例敏感的语言吗?PHP是对病例敏感的语言吗?Apr 28, 2025 pm 04:55 PM

PHP的情况敏感性各不相同:功能不敏感,而变量和类是敏感的。最佳实践包括一致的命名和使用对案例不敏感的功能进行比较。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

EditPlus 中文破解版

EditPlus 中文破解版

体积小,语法高亮,不支持代码提示功能

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

WebStorm Mac版

WebStorm Mac版

好用的JavaScript开发工具

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

功能强大的PHP集成开发环境

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)