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 相关文章推荐
joomla内置的表单验证功能使用方法
Jun 11 PHP
php开发环境配置记录
Jan 14 PHP
php笔记之:数据类型与常量的使用分析
May 14 PHP
php实现按文件名搜索文件的远程文件查找器
May 10 PHP
迪菲-赫尔曼密钥交换(Diffie?Hellman)算法原理和PHP实现版
May 12 PHP
php数组比较实现查找连续数的方法
Jul 29 PHP
PHP的CURL方法curl_setopt()函数案例介绍(抓取网页,POST数据)
Dec 14 PHP
php+redis实现注册、删除、编辑、分页、登录、关注等功能示例
Feb 15 PHP
PHP定义字符串的四种方式详解
Feb 06 PHP
PHP使用zlib扩展实现GZIP压缩输出的方法详解
Apr 09 PHP
thinkphp5修改view到根目录实例方法
Jul 02 PHP
PHP正则之正向预查与反向预查讲解与实例
Apr 06 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
分页显示Oracle数据库记录的类之二
2006/10/09 PHP
PHP提示Deprecated: mysql_connect(): The mysql extension is deprecated的解决方法
2014/08/28 PHP
wordpress网站转移到本地运行测试的方法
2017/03/15 PHP
获取dom元素那些讨厌的位置封装代码
2010/06/23 Javascript
从盛大通行证上摘下来的身份证验证js代码
2011/01/11 Javascript
关闭页面时window.location事件未执行的原因分析及解决方案
2014/09/01 Javascript
jquery实现侧边弹出的垂直导航
2014/12/09 Javascript
node.js中的fs.lstat方法使用说明
2014/12/16 Javascript
js实现兼容性好的微软官网导航下拉菜单效果
2015/09/07 Javascript
小巧强大的jquery layer弹窗弹层插件
2015/12/06 Javascript
Node.js connect ECONNREFUSED错误解决办法
2016/09/15 Javascript
jquery事件绑定解绑机制源码解析
2016/09/19 Javascript
jQuery的Read()方法代替原生JS详解
2016/11/08 Javascript
多种方式实现js图片预览
2016/12/12 Javascript
jquery实现图片跟随鼠标的实例
2017/10/17 jQuery
layer关闭弹出窗口触发表单提交问题的处理方法
2019/09/25 Javascript
浅谈Vue 函数式组件的使用技巧
2020/06/16 Javascript
原生JavaScript实现进度条
2021/02/19 Javascript
在IIS服务器上以CGI方式运行Python脚本的教程
2015/04/25 Python
Python求导数的方法
2015/05/09 Python
Python使用自带的ConfigParser模块读写ini配置文件
2016/06/26 Python
TensorFlow查看输入节点和输出节点名称方式
2020/01/04 Python
Python *args和**kwargs用法实例解析
2020/03/02 Python
Python接口自动化测试的实现
2020/08/28 Python
Python实现FTP文件定时自动下载的步骤
2020/12/19 Python
详解pandas apply 并行处理的几种方法
2021/02/24 Python
html5教程画矩形代码分享
2013/12/04 HTML / CSS
Html5让容器充满屏幕高度或自适应剩余高度的布局实现
2020/05/14 HTML / CSS
美国精品地毯网站:Boutique Rugs
2020/03/04 全球购物
如何用Lucene索引数据库
2016/02/23 面试题
高中毕业自我鉴定
2013/12/16 职场文书
党员创先争优承诺书
2014/03/26 职场文书
给校长的建议书500字
2014/05/15 职场文书
电子商务专业毕业生求职信
2014/06/12 职场文书
致800米运动员广播稿(10篇)
2014/10/17 职场文书
追悼会悼词大全
2015/06/23 职场文书