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 相关文章推荐
用PHP实现小型站点广告管理
Oct 09 PHP
php 中include()与require()的对比
Oct 09 PHP
PHP下通过exec获得计算机的唯一标识[CPU,网卡 MAC地址]
Jun 09 PHP
基于php常用正则表达式的整理汇总
Jun 08 PHP
ThinkPHP中的create方法与自动令牌验证实例教程
Aug 22 PHP
PHP自带ZIP压缩、解压缩类ZipArchiv使用指南
Mar 03 PHP
PHP中array_keys和array_unique函数源码的分析
Feb 26 PHP
PHP实现二维数组去重功能示例
Jan 12 PHP
PHP获取数据库表中的数据插入新的表再原删除数据方法
Oct 12 PHP
PHP中“=&gt;
Mar 01 PHP
php基于协程实现异步的方法分析
Jul 17 PHP
laravel请求参数校验方法
Oct 10 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
《雄兵连》《烈阳天道》真的来了
2020/07/13 国漫
别人整理的服务器变量:$_SERVER
2006/10/20 PHP
php set_magic_quotes_runtime() 函数过时解决方法
2010/07/08 PHP
php获取四位字母和数字的随机数的实现方法
2015/01/09 PHP
ThinkPHP 3.2.2实现事务操作的方法
2017/05/05 PHP
jquery ajax学习笔记2 使用XMLHttpRequest对象的responseXML
2011/10/16 Javascript
快速查找数组中的某个元素并返回下标示例
2013/09/03 Javascript
jquery数据验证插件(自制,简单,练手)实例代码
2013/10/24 Javascript
js实现的tab标签切换效果代码分享
2015/08/25 Javascript
jquery原理以及学习技巧介绍
2015/11/11 Javascript
BootStrap Datetimepicker 汉化的实现代码
2017/02/10 Javascript
Bootstrap fileinput组件封装及使用详解
2017/03/10 Javascript
protractor的安装与基本使用教程
2017/07/07 Javascript
jquery tmpl模板(实例讲解)
2017/09/02 jQuery
使用JS中的Replace()方法遇到的问题小结
2017/10/20 Javascript
AngularJS实现controller控制器间共享数据的方法示例
2017/10/30 Javascript
Angular 开发学习之Angular CLI的安装使用
2017/12/31 Javascript
对vue事件的延迟执行实例讲解
2018/08/28 Javascript
layui+SSM的数据表的增删改实例(利用弹框添加、修改)
2019/09/27 Javascript
javascript将16进制的字符串转换为10进制整数hex
2020/03/05 Javascript
微信小程序自定义底部弹出框功能
2020/11/18 Javascript
Python抓取Discuz!用户名脚本代码
2013/12/30 Python
举例讲解Linux系统下Python调用系统Shell的方法
2015/11/07 Python
用pandas按列合并两个文件的实例
2018/04/12 Python
python实现贪吃蛇游戏
2020/03/21 Python
python使用正则筛选信用卡
2019/01/27 Python
如何在Django中添加没有微秒的 DateTimeField 属性详解
2019/01/30 Python
Python学习笔记之Django创建第一个数据库模型的方法
2019/08/07 Python
python 3.6.7实现端口扫描器
2019/09/04 Python
python3 求约数的实例
2019/12/05 Python
python中property和setter装饰器用法
2019/12/19 Python
tensorflow 固定部分参数训练,只训练部分参数的实例
2020/01/20 Python
美国最大的半成品净菜电商:Blue Apron(蓝围裙)
2018/04/27 全球购物
求职推荐信
2013/10/28 职场文书
先进个人事迹材料
2014/01/25 职场文书
学校运动会开幕词
2016/03/03 职场文书