php类中private属性继承问题分析


Posted in PHP onNovember 01, 2012

请仔细看这句话 如果父类有私有的属性。那么父类的方法只为父类的私有属性服务。
下面通过一系列列子来加深理解.
这个例子看起来很奇怪,在子类中重新定义了一个属性$sal,系统却返回了父类的属性。

<? 
class employee{ 
private $sal=3000; 
//protected $sal=3000; 
public function getSal(){ 
return $this->sal; 
} 
} 
class Manager extends employee { 
protected $sal=5000; public function getParentSal(){ 
//这里返回的是父类的private属性. 
return parent::getSal(); 
} 
} 
$manager = new Manager(); 
echo "PHP ".phpversion()."<br>"; 
echo $manager->getSal(); 
echo "<br>"; 
echo "parent's \$sal ".$manager->getParentSal(); 
?>

程序运行结果:
PHP 5.3.8 
3000 
parent's $sal 3000

如果父类中的属性被子类重写了。结果是这样的。注意 第5行的属性定义变成了protected。
<? 
class employee{ 
//private $sal=3000; 
protected $sal=3000; 
public function getSal(){ 
return $this->sal; 
} 
} class Manager extends employee { 
protected $sal=5000; 
public function getParentSal(){ 
//这里返回的是父类的private属性. 
return parent::getSal(); 
} 
} 
$manager = new Manager(); 
echo "PHP ".phpversion()."<br>"; 
echo $manager->getSal(); 
echo "<br>"; 
echo "parent's \$sal ".$manager->getParentSal(); 
?>

程序运行结果:
PHP 5.3.8 
5000 
parent's $sal 5000

第一个列子中 父类的private $sal没有被重写 所以$manager->getSal()这个父类的方法 调用的是父类自己的私有属性$sal 此时内存中有两个$sal
第二个列子中 父类的protected $sal被重写 $manager->getSal()这个父类的方法 调用已经被重写的$sal 父类的$sal在内存中是不存在的 此时内存中只有一个$sal
接下来看第三个列子
子类中重写的方法对当前private有效。
<? 
class employee{ 
private $sal=3000; 
public function getSal(){ 
return $this->sal; 
} 
} class Manager extends employee { 
private $sal=5000; 
//重写过的方法 
public function getSal(){ 
return $this->sal; 
} 
public function getParentSal(){ 
//这里返回的是父类的private属性. 
return parent::getSal(); 
} 
} 
$manager = new Manager(); 
echo "PHP ".phpversion()."<br>"; 
echo $manager->getSal(); 
echo "<br>"; 
echo "parent's \$sal ".$manager->getParentSal(); 
?>

运行结果
PHP 5.3.8 
5000 
parent's $sal 3000

这个列子中子类重写getSal()方法 所以他调用的是子类的属性
如果你注释子类的这一行
//private $sal=5000;
你会发现一个错误:Notice: Undefined property: Manager::$sal in E:\wamp\www\oo\2-5\2-5-3.php on line 14
如果注释掉12行的子类重写方法 那么echo $manager->getSal();得到的结果是 父类的私有属性$sal 3000

打开zend调试状态看看,内存中的情况。注意最下面,有两个$sal 。分别是 3000 和 5000 。

<? 
class employee{ 
private $sal=3000; 
public function getSal(){ 
return $this->sal; 
} 
} 
class Manager extends employee { 
protected $sal=5000; 
public function getParentSal(){ 
return $this->sal; 
} 
} 
$manager = new Manager(); 
echo "PHP ".phpversion()."<br>"; 
echo $manager->getSal(); 
?>

程序运行结果:
PHP 5.3.8 
3000

将父类的属性$sal 改成 protected ,子类重写了父类的属性。在内存中只有一个 $sal 。
<? 
class employee{ 
protected $sal=3000; 
public function getSal(){ 
return $this->sal; 
} 
} 
class Manager extends employee { 
protected $sal=5000; 
public function getParentSal(){ 
return $this->sal; 
} 
} 
$manager = new Manager(); 
echo "PHP ".phpversion()."<br>"; 
echo $manager->getSal(); ?>

程序运行结果:
PHP 5.3.8 
5000

如果你学过java,你会觉得这一切都是很难理解的。
在Java中当子类被创建时,父类的属性和方法在内存中都被创建,甚至构造函数也要被调用。
PHP5不是这样,PHP5调用父类用的是parent:: 而不是 parent-> ,这足以说明PHP5不想在内存中让父类也被创建。PHP5想让继承变的比Java更简单。
适应下就好。
PHP 相关文章推荐
珊瑚虫IP库浅析
Feb 15 PHP
PHP 进程锁定问题分析研究
Nov 24 PHP
PHP中使用unset销毁变量并内存释放问题
Jul 05 PHP
thinkPHP的Html模板标签使用方法
Nov 13 PHP
关于mysql字符集设置了character_set_client=binary 在gbk情况下会出现表描述是乱码的情况
Jan 06 PHP
php模板原理讲解
Nov 13 PHP
php中{}大括号是什么意思
Dec 01 PHP
php实现插入数组但不影响原有顺序的方法
Mar 27 PHP
php实现paypal 授权登录
May 28 PHP
列举PHP的Yii 2框架的开发优势
Jul 03 PHP
PHP实现数组array转换成xml的方法
Jul 19 PHP
Discuz不使用插件实现简单的打赏功能
Mar 21 PHP
用php实现百度网盘图片直链的代码分享
Nov 01 #PHP
php curl 伪造IP来源的实例代码
Nov 01 #PHP
php中将指针移动到数据集初始位置的实现代码[mysql_data_seek]
Nov 01 #PHP
php eval函数用法 PHP中eval()函数小技巧
Oct 31 #PHP
php eval函数用法总结
Oct 31 #PHP
PHP5下$_SERVER变量不再受magic_quotes_gpc保护的弥补方法
Oct 31 #PHP
php图片加中文水印实现代码分享
Oct 31 #PHP
You might like
php一些公用函数的集合
2008/03/27 PHP
php使用wordwrap格式化文本段落的方法
2015/03/17 PHP
php封装好的人民币数值转中文大写类
2015/12/20 PHP
Yii2验证器(Validator)用法分析
2016/07/23 PHP
浅谈PHP接入(第三方登录)QQ登录 OAuth2.0 过程中遇到的坑
2017/10/13 PHP
PHP-FPM和Nginx的通信机制详解
2019/02/01 PHP
50个优秀经典PHP算法大集合 附源码
2020/08/26 PHP
JS 控制CSS样式表
2009/08/20 Javascript
跨浏览器的事件对象介绍
2012/06/27 Javascript
jQuery实现可拖动的浮动层完整代码
2013/05/27 Javascript
JS获取各种浏览器窗口大小的方法
2014/01/14 Javascript
JQuery异步加载PartialView的方法
2016/06/07 Javascript
【经典源码收藏】基于jQuery的项目常见函数封装集合
2016/06/07 Javascript
JavaScript提升性能的常用技巧总结【经典】
2016/06/20 Javascript
javaScript嗅探执行神器-sniffer.js
2017/02/14 Javascript
Angular.Js中ng-include指令的使用与实现
2017/05/07 Javascript
js+html5实现侧滑页面效果
2017/07/15 Javascript
js 中rewrap-ajax.js插件实例代码
2017/10/20 Javascript
详解Vue取消eslint语法限制
2018/08/04 Javascript
vue-cli 使用axios的操作方法及整合axios的多种方法
2018/09/12 Javascript
vue+iview 兼容IE11浏览器的实现方法
2019/01/07 Javascript
详解JavaScript 的变量
2019/03/08 Javascript
Python多进程并发(multiprocessing)用法实例详解
2015/06/02 Python
python如何发布自已pip项目的方法步骤
2018/10/09 Python
Pyqt5 实现跳转界面并关闭当前界面的方法
2019/06/19 Python
python3实现的zip格式压缩文件夹操作示例
2019/08/17 Python
Python绘制二维曲线的日常应用详解
2019/12/04 Python
Python unittest 自动识别并执行测试用例方式
2020/03/09 Python
美国嘻哈首饰购物网站:Hip Hop Bling
2016/12/30 全球购物
Sephora丝芙兰泰国官方网站:国际知名化妆品购物
2017/11/15 全球购物
银行授权委托书格式
2014/10/10 职场文书
保证书格式
2015/01/16 职场文书
搬迁通知
2015/04/20 职场文书
职工食堂管理制度
2015/08/06 职场文书
pytorch 6 batch_train 批训练操作
2021/05/28 Python
springmvc直接不经过controller访问WEB-INF中的页面问题
2022/02/24 Java/Android