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 相关文章推荐
从C/C++迁移到PHP——判断字符类型的函数
Oct 09 PHP
真正的ZIP文件操作类(php)
Jul 21 PHP
PHP下10件你也许并不了解的事情
Sep 11 PHP
PHP通过正则表达式下载图片到本地的实现代码
Sep 19 PHP
ubuntu10.04配置 nginx+php-fpm模式的详解
Jun 03 PHP
遭遇php的in_array低性能问题
Sep 17 PHP
php实现邮件发送并带有附件
Jan 24 PHP
php一个解析字符串排列数组的方法
May 12 PHP
php fseek函数读取大文件两种方法
Oct 12 PHP
总结一些PHP中好用但又容易忽略的小知识
Jun 02 PHP
php数据库的增删改查 php与javascript之间的交互
Aug 31 PHP
解决PHP Opcache 缓存刷新、代码重载出现无法更新代码的问题
Aug 24 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桌面中心(二) 数据库写入
2007/03/11 PHP
PHP实现图片压缩的两则实例
2014/07/19 PHP
基于PHP实现数据分页显示功能
2016/05/26 PHP
原生的html元素选择器类似jquery选择器
2014/10/15 Javascript
JavaScript制作简易的微信打飞机
2015/03/31 Javascript
JS+CSS实现大气清新的滑动菜单效果代码
2015/10/22 Javascript
Window.Open打开窗体和if嵌套代码
2016/04/15 Javascript
举例讲解jQuery对DOM元素的向上遍历、向下遍历和水平遍历
2016/07/07 Javascript
Vue组件BootPage实现简单的分页功能
2016/09/12 Javascript
纯javaScript、jQuery实现个性化图片轮播【推荐】
2017/01/08 Javascript
JavaScript中匿名函数的递归调用
2017/01/22 Javascript
基于JSON数据格式详解
2017/08/31 Javascript
JavaScript设计模式之建造者模式实例教程
2018/07/02 Javascript
详解JavaScript添加给定的标签选项
2018/09/17 Javascript
Next.js项目实战踩坑指南(笔记)
2018/11/29 Javascript
Vue替代marquee标签超出宽度文字横向滚动效果
2019/12/09 Javascript
Angular5整合富文本编辑器TinyMCE的方法(汉化+上传)
2020/05/26 Javascript
js实现抽奖功能
2020/11/24 Javascript
Python3实现将文件归档到zip文件及从zip文件中读取数据的方法
2015/05/22 Python
python密码错误三次锁定(实例讲解)
2017/11/14 Python
Python2.7环境Flask框架安装简明教程【已测试】
2018/07/13 Python
Django之提交表单与前后端交互的方法
2019/07/19 Python
Python获取时间戳代码实例
2019/09/24 Python
python如何获得list或numpy数组中最大元素对应的索引
2020/11/16 Python
Django-celery-beat动态添加周期性任务实现过程解析
2020/11/26 Python
html5的新增的标签和废除的标签简要概述
2013/02/20 HTML / CSS
微信小程序“圣诞帽”的实现思路详解
2017/12/28 HTML / CSS
美丽的现代设计家具:2Modern
2018/07/26 全球购物
AJAX的全称是什么
2012/11/06 面试题
旅游管理本科生求职信
2013/10/14 职场文书
学习雷锋活动总结
2014/04/29 职场文书
转让协议书
2015/01/27 职场文书
2015年保险公司个人工作总结
2015/05/22 职场文书
2016计算机专业毕业生自荐信
2016/01/28 职场文书
2019年自助餐厅创业计划书模板
2019/08/22 职场文书
python中的plt.cm.Paired用法说明
2021/05/31 Python