php面向对象全攻略 (八)重载新的方法


Posted in PHP onSeptember 30, 2009

12.重载新的方法
在学习PHP 这种语言中你会发现,PHP 中的方法是不能重载的,所谓的方法重载就是
定义相同的方法名,通过“参数的个数”不同或“参数的类型”不同,来访问我们的相同方法
名的不同方法。但是因为PHP 是弱类型的语言,所以在方法的参数中本身就可以接收不同类
型的数据,又因为PHP 的方法可以接收不定个数的参数,所以通过传递不同个数的参数调用
不相同方法名的不同方法也是不成立的。所以在PHP 里面没有方法重载。不能重载也就是在
你的项目中不能定义相同方法名的方法。另外,因为PHP 没有名子空间的概念,在同一个页
面和被包含的页面中不能定义相同名称的方法,也不能定义和PHP 给我提供的方法重名,当
然在同一个类中也不能定义相同名称的方法。
我们这里所指的重载新的方法所指的是什么呢?其实我们所说的重载新的方法就是子类
覆盖父类的已有的方法,那为什么要这么做呢?父类的方法不是可以继承过来直接用吗?但
有一些情况是我们必须要覆盖的,比如说我们前面提到过的例子里面,“Person”这个人类里
面有一个“说话”的方法,所有继承“Person”类的子类都是可以“说话”的,我们“Student”
类就是“Person”类的子类,所以“Student”的实例就可以“说话”了,但是人类里面“说
话”的方法里面说出的是“Person”类里面的属性,而“Student”类对“Person”类进行了扩
展,又扩展出了几个新的属性,如果使用继承过来的“say()”说话方法的话,只能说出从
“Person”类继承过来的那些属性,那么新扩展的那些属性使用这个继承过来的“say()”的
方法就说不出来了,那有的人就问了,我在“Student”这个子类中再定义一个新的方法用于
说话,说出子类里面所有的属性不就行了吗?一定不要这么做,从抽象的角度来讲,一个“学
生”不能有两种“说话”的方法,就算你定义了两个不同的说话的方法,可以实现你想要的
功能,被继承过来的那个“说话“方法可能没有机会用到了,而且是继承过来的你也删不掉。
这个时候我们就要用到覆盖了。
虽然说在PHP 里面不能定义同名的方法,但是在父子关系的两个类中,我们可以在子类
中定义和父类同名的方法,这样就把父类中继承过来的方法覆盖掉了。
代码片段

<? 
//定义一个“人”类做为父类 
class Person{ 
//下面是人的成员属性 
var $name; //人的名子 
var $sex; //人的性别 
var $age; //人的年龄 
//定义一个构造方法参数为属性姓名$name、性别$sex和年龄$age进行赋值 
function __construct($name, $sex, $age){ 
$this->name=$name; 
$this->sex=$sex; 
$this->age=$age; 
} 
//这个人可以说话的方法, 说出自己的属性 
function say() { 
echo "我的名子叫:".$this->name." 性别:".$this->sex." 我的年龄是:".$this->age."<br>"; 
} 
} 
class Student extends Person 
{ 
var $school; //学生所在学校的属性 
//这个学生学习的方法 
function study() { 
echo "我的名子叫:".$this->name." 我正在”.$this->school.”学习<br>"; 
} 
//这个学性可以说话的方法, 说出自己所有的属性,覆盖了父类的同名方法 
function say() { 
echo "我的名子叫:".$this->name." 性别:".$this->sex." 我的年龄是:".$this->age."我在 
".$this->school."上学.<br>"; 
} 
} 
?>

上面的例子,我们就在“Student”子类里覆盖了继承父类里面的“say()”的方法,通过
覆盖我们就实现了对“方法”扩展。
但是,像这样做虽然解决了我们上面说的问题,但是在实际开发中,一个方法不可能就
一条代码或是几条代码,比如说“Person”类里面的“say()”方法有里面有100 条代码,如
果我们想对这个方法覆盖保留原有的功能外加上一点点功能,就要把原有的100 条代码重写
一次,再加上扩展的几条代码,这还算是好的,而有的情况,父类中的方法是看不见原代码
的,这个时候你怎么去重写原有的代码呢?我们也有解决的办法,就是在子类这个方法中可
以调用到父类中被覆盖的方法,也就是把被覆盖的方法原有的功能拿过来再加上自己的一点
功能,可以通过两种方法实现在子类的方法中调用父类被覆盖的方法:
一种是使用父类的“类名::“来调用父类中被覆盖的方法;
一种是使用“parent::”的方试来调用父类中被覆盖的方法;
代码片段
class Student extends Person{ 
var $school; //学生所在学校的属性 
//这个学生学习的方法 
function study() { 
echo "我的名子叫:".$this->name." 我正在”.$this->school.”学习<br>"; 
} 
//这个学性可以说话的方法, 说出自己所有的属性,覆盖了父类的同名方法 
function say() { 
//使用父类的“类名::“来调用父类中被覆盖的方法; 
// Person::say(); 
//或者使用“parent::”的方试来调用父类中被覆盖的方法; 
parent::say(); 
//加上一点自己的功能 
echo “我的年龄是:".$this->age."我在".$this->school."上学.<br>"; 
} 
}

现在用两种方式都可以访问到父类中被覆盖的方法,我们选那种方式最好呢?用户可能
会发现自己写的代码访问了父类的变量和函数。如果子类非常精炼或者父类非常专业化的时
候尤其是这样。不要用代码中父类文字上的名字,应该用特殊的名字parent,它指的就是子
类在extends 声明中所指的父类的名字。这样做可以避免在多个地方使用父类的名字。如果继
承树在实现的过程中要修改,只要简单地修改类中extends 声明的部分。
同样,构造方法在子类中如果没有声明的话,也可以使用父类中的构造方法,如果子类
中重新定义了一个构造方法也会覆盖掉父类中的构造方法,如果想使用新的构造方法为所有
属性赋值也可以用同样的方式。
代码片段
class Student extends Person{ 
var $school; //学生所在学校的属性 
function __construct($name, $sex, $age, $school){ 
//使用父类中的方法为原有的属性赋值 
parent::__construct($name, $sex, $age); 
$this->school=$school; 
} 
//这个学生学习的方法 
function study() { 
echo "我的名子叫:".$this->name." 我正在”.$this->school.”学习<br>"; 
} 
//这个人可以说话的方法, 说出自己的属性 
function say() { 
parent::say(); 
//加上一点自己的功能 
echo “我的年龄是:".$this->age."我在".$this->school."上学.<br>";
PHP 相关文章推荐
php环境配置 php5 MySQL5 apache2 phpmyadmin安装与配置图文教程
Mar 16 PHP
PHP开发中四种查询返回结果分析
Jan 02 PHP
深入理解PHP原理之错误抑制与内嵌HTML分析
May 02 PHP
thinkphp3.0 模板中函数的使用
Nov 13 PHP
php实现对两个数组进行减法操作的方法
Apr 17 PHP
wampserver改变默认网站目录的办法
Aug 05 PHP
10个超级有用的PHP代码片段果断收藏
Sep 23 PHP
PHP文件缓存类实现代码
Oct 26 PHP
yii数据库的查询方法
Dec 28 PHP
PHP实现查询手机归属地的方法详解
Apr 28 PHP
PHP面向对象程序设计之对象克隆clone和魔术方法__clone()用法分析
Jun 12 PHP
PHP手机号码及邮箱正则表达式实例解析
Jul 11 PHP
php面向对象全攻略 (七) 继承性
Sep 30 #PHP
php面向对象全攻略 (六)__set() __get() __isset() __unset()的用法
Sep 30 #PHP
php面向对象全攻略 (五) 封装性
Sep 30 #PHP
php面向对象全攻略 (四)构造方法与析构方法
Sep 30 #PHP
php面向对象全攻略 (三)特殊的引用“$this”的使用
Sep 30 #PHP
php面向对象全攻略 (二) 实例化对象 使用对象成员
Sep 30 #PHP
php面向对象全攻略 (一) 面向对象基础知识
Sep 30 #PHP
You might like
特转载一高手总结PHP学习资源和链接.
2006/12/05 PHP
php简单封装了一些常用JS操作
2007/02/25 PHP
win7+apache+php+mysql环境配置操作详解
2013/06/10 PHP
PHP、Nginx、Apache中禁止网页被iframe引用的方法
2020/10/01 PHP
PHP封装的MSSql操作类完整实例
2016/05/26 PHP
利用php获得flv视频长度的实例代码
2017/10/26 PHP
PHP删除数组中指定下标的元素方法
2018/02/03 PHP
Javascript 代码也可以变得优美的实现方法
2009/06/22 Javascript
javascript 选择文件夹对话框(web)
2009/07/07 Javascript
javascrpt绑定事件之匿名函数无法解除绑定问题
2012/12/06 Javascript
JavaScript获取图片真实大小代码实例
2014/09/24 Javascript
js实现class样式的修改、添加及删除的方法
2015/01/20 Javascript
JavaScript获取短信验证码(周期性)
2016/12/29 Javascript
Web技术实现移动监测的介绍
2017/09/18 Javascript
基于 Vue.js 之 iView UI 框架非工程化实践记录(推荐)
2017/11/21 Javascript
js实现简易点击切换显示或隐藏
2020/11/29 Javascript
[03:38]TI4西雅图DOTA2前线报道 71专访
2014/07/08 DOTA
python类型强制转换long to int的代码
2013/02/10 Python
Python采用Django开发自己的博客系统
2020/09/29 Python
centos6.4下python3.6.1安装教程
2017/07/21 Python
Python调用C语言的方法【基于ctypes模块】
2018/01/22 Python
pandas获取groupby分组里最大值所在的行方法
2018/04/20 Python
python3.X 抓取火车票信息【修正版】
2018/06/19 Python
Django基础知识与基本应用入门教程
2018/07/20 Python
Python使用folium excel绘制point
2019/01/03 Python
树莓派使用python-librtmp实现rtmp推流h264的方法
2019/07/22 Python
python使用scapy模块实现ARP扫描的过程
2021/01/21 Python
迪士尼英国官方商店:shopDisney UK
2019/09/21 全球购物
厂长助理岗位职责
2013/12/27 职场文书
《学会待客》教学反思
2014/02/22 职场文书
临时工聘用合同协议书
2014/10/29 职场文书
幼儿学前班评语
2014/12/29 职场文书
运动会入场词
2015/07/18 职场文书
学校体育节班级口号
2015/12/25 职场文书
只需要这一行代码就能让python计算速度提高十倍
2021/05/24 Python
PostgreSQL常用字符串分割函数整理汇总
2022/07/07 PostgreSQL