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
用文本文件实现的动态实时发布新闻的程序
Oct 09 PHP
php Smarty date_format [格式化时间日期]
Mar 15 PHP
PHP $_FILES函数详解
Mar 09 PHP
php通过function_exists检测函数是否存在的方法
Mar 18 PHP
php校验表单检测字段是否为空的方法
Mar 20 PHP
PHP中常见的缓存技术实例分析
Sep 23 PHP
PHP session会话操作技巧小结
Sep 27 PHP
PHP实现的简单AES加密解密算法实例
May 29 PHP
php获取'/'传参的值简单方法
Jul 13 PHP
PHP迭代与递归实现无限级分类
Aug 28 PHP
php如何比较两个浮点数是否相等详解
Feb 12 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编程注意事项的小结
2013/04/27 PHP
教你如何快捷的使用cmd访问mysql小技巧
2014/05/26 PHP
PHP使用DOMDocument类生成HTML实例(包含常见标签元素)
2014/06/25 PHP
PHP的简单跳转提示的实现详解
2019/03/14 PHP
javascript &amp;&amp;和||运算法的另类使用技巧
2009/11/28 Javascript
JS 文件大小判断的实现代码
2010/04/07 Javascript
js获取url中&quot;?&quot;后面的字串方法
2014/05/15 Javascript
jQuery通过点击行来删除HTML表格行的实现示例
2014/09/10 Javascript
jquery操作复选框checkbox的方法汇总
2015/02/05 Javascript
编写高性能Javascript代码的N条建议
2015/10/12 Javascript
实例代码详解javascript实现窗口抖动及qq窗口抖动
2016/01/04 Javascript
理解javascript中的with关键字
2016/02/15 Javascript
浅析AMD CMD CommonJS规范--javascript模块化加载学习心得总结
2016/03/16 Javascript
jQuery实现立体式数字动态增加(animate方法)
2016/12/21 Javascript
Vue.js 递归组件实现树形菜单(实例分享)
2016/12/21 Javascript
使用微信内嵌H5网页解决JS倒计时失效问题
2017/01/13 Javascript
ES6字符串模板,剩余参数,默认参数功能与用法示例
2017/04/06 Javascript
关于angular js_$watch监控属性和对象详解
2017/04/24 Javascript
vue树形结构获取键值的方法示例
2018/06/21 Javascript
详谈Python 窗体(tkinter)表格数据(Treeview)
2018/10/11 Python
python二元表达式用法
2019/12/04 Python
浅谈keras通过model.fit_generator训练模型(节省内存)
2020/06/17 Python
python爬虫beautifulsoup库使用操作教程全解(python爬虫基础入门)
2021/02/19 Python
Asics日本官网:鬼冢八喜郎创立的跑鞋运动品牌
2017/10/18 全球购物
Columbia Sportswear法国官网:全球户外品牌
2020/09/25 全球购物
公务员年总结的自我评价
2013/10/25 职场文书
三年级语文教学反思
2014/02/01 职场文书
龙潭大峡谷导游词
2015/02/10 职场文书
幼儿园教师自荐书
2015/03/06 职场文书
党员“一帮一”活动总结
2015/05/07 职场文书
2015年民主评议党员工作总结
2015/05/19 职场文书
酒会开场白大全
2015/06/01 职场文书
幼儿园奖惩制度范本
2015/08/05 职场文书
Python学习之异常中的finally使用详解
2022/03/16 Python
python使用BeautifulSoup 解析HTML
2022/04/24 Python
阿里云 Windows server 2019 配置FTP
2022/04/28 Servers