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和ACCESS写聊天室(十)
Oct 09 PHP
基于pear auth实现登录验证
Feb 26 PHP
YII2.0之Activeform表单组件用法实例
Jan 09 PHP
Zend Framework教程之前端控制器Zend_Controller_Front用法详解
Mar 07 PHP
php短信接口代码
May 13 PHP
Linux平台PHP5.4设置FPM线程数量的方法
Nov 09 PHP
php 函数使用可变数量的参数方法
May 02 PHP
php+laravel依赖注入知识点总结
Nov 04 PHP
php获取小程序码的实现代码(B类接口)
Jun 13 PHP
基于PHP实现解密或加密Cloudflar邮箱保护
Jun 24 PHP
PhpSpreadsheet设置单元格常用操作汇总
Nov 13 PHP
浅谈如何提高PHP代码质量之单元测试
May 28 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/04/09 PHP
对淘宝URL中ID提取的PHP代码
2013/09/01 PHP
php基于PDO连接MSSQL示例DEMO
2016/07/13 PHP
PHP二维数组去重实例分析
2016/11/18 PHP
Jquery中增加参数与Json转换代码
2009/11/20 Javascript
javascript函数定义的几种区别小结
2014/01/06 Javascript
JS数字抽奖游戏实现方法
2015/05/04 Javascript
JavaScript中Date对象的常用方法示例
2015/10/24 Javascript
初步了解javascript面向对象
2015/11/09 Javascript
学习JavaScript设计模式之享元模式
2016/01/18 Javascript
jQuery配合coin-slider插件制作幻灯片效果的流程解析
2016/05/13 Javascript
jQuery 中ajax异步调用的四种方式
2016/06/28 Javascript
mvc中form表单提交的三种方式(推荐)
2016/08/10 Javascript
分享JS代码实现鼠标放在输入框上输入框和图片同时更换样式
2016/09/01 Javascript
微信小程序(三):网络请求
2017/01/13 Javascript
对Vue table 动态表格td可编辑的方法详解
2018/08/28 Javascript
在vue项目中使用Jquery-contextmenu插件的步骤讲解
2019/01/27 jQuery
Node.JS在命令行中检查Chrome浏览器是否安装并打开指定网址
2019/05/21 Javascript
Webpack中SplitChunksPlugin 配置参数详解
2020/03/24 Javascript
Python开发的HTTP库requests详解
2017/08/29 Python
python实现用户管理系统
2018/01/10 Python
python3.7 的新特性详解
2019/07/25 Python
python队列原理及实现方法示例
2019/11/27 Python
jupyter 中文乱码设置编码格式 避免控制台输出的解决
2020/04/20 Python
美国奢侈品购物平台:Orchard Mile
2018/05/02 全球购物
ProForm英国站点:健身房和健身器材网上商店
2019/06/05 全球购物
几个常见的软件测试问题
2016/09/07 面试题
Overload和Override的区别
2012/09/02 面试题
党委书记岗位职责
2013/11/24 职场文书
菜篮子工程实施方案
2014/03/08 职场文书
教育英语专业毕业生的求职信
2014/03/13 职场文书
我的大学生活演讲稿
2014/04/25 职场文书
反洗钱宣传活动总结
2014/08/26 职场文书
公司试用期员工自我评价
2014/09/17 职场文书
四风对照检查材料范文
2014/09/27 职场文书
小学班主任工作随笔
2015/08/15 职场文书