子类重载父类的方法“parent:方法名”
在PHP中不能定义重名的函数,也包括不能再同一个类中定义重名的方法,所以也就没有方法重载。单在子类中可以定义和父类重名的方法,因为父类的方法已经在子类中存在,这样在子类中就可以把从父类中继承过来的方法重写。
子类中重载父类的方法就是在子类中覆盖从父类中继承过来的方法,父类中的方法被子类继承过来不就可以直接使用吗?为什么还要重载呢?因为有一些情况我们必须要覆盖的。例如,有一个“鸟”类,在这个类中定义了鸟的通用方法“飞翔”。将“鸵鸟”类作为它的子类,就会将“飞翔”的方法继承过来,但只要一调用“鸵鸟”类中的这个“飞翔”的方法,鸵鸟就会飞走。虽然鸵鸟是不会飞的,但其他特性都具有“鸟类”的特性,所以在声明“鸵鸟”类时还是可以继承“鸟”类的,但必须在“鸵鸟”类中将“鸟”类中继承过来的“飞翔”方法改写,就需要在子类中重载父类中的方法。
在下面的例子中,声明的Person类中有一个“说话”方法,Student类继承Person类后可以直接使用“说话”方法。但Person类中的“说话”方法只能说出它自己的成员属性,而Student类对Person类进行了扩展,多添加了几个新的成员属性。代码如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
<?php class Person{ protected $name ; protected $sex ; protected $Wage ; function __construct( $name = "" , $sex = "男" , $age =1){ $this ->name = $name ; $this ->sex = $sex ; $this ->age = $age ; } //在人类中声明一个通用的说话方法,介绍一下自己 function say(){ echo "我的名字:" . $this -> name. ",性别:" . $this ->sex. ",年龄:" . $this ->age. "。<br>" ; } } //声明一个学生类,使用extends关键字扩展(继承)person类 class Student extends Person { private $school ; //在学生类中声明一个所在学校school的成员属性 //覆盖父类中的构造方法,在参数列表中添加一个学校属性,用来创建对象并初始化成员属性 function __construct( $name = "" , $sex = "男" , $age =1, $school = "" ){ $this ->name = $name ; $this ->sex = $sex ; $this ->age = $age ; $this ->school = $school ; } function study(){ echo $this ->name. "正在" . $this ->school. "学习<br>" ; } //定义一个和父类中同名的方法,将父类中的说话方法覆盖并重写,多说出所在的学校名称 function say(){ echo "我的名字:" . $this ->name. ",性别:" . $this ->sex. ",年龄:" . $this ->age. ",在" . $this ->school. "学校上学<br>" ; } } $student = new Student( "张三" , "男" ,20, "edu" ); //创建一个学生对象,并传给一个学校名称参数 $student -> say(); //调用学生类中覆盖父类的说话方法 ?> |
改程序运行后输出的结果为:
我的名字叫:张三,性别:男,我的年龄是:20,在edu学校上学
在PHP中,提供了在子类重载的方法中调用父类被覆盖方法的功能。这样就可以在子类重写的方法中,继续使用从父类继承过来并被覆盖的方法,然后再按要求多添加一些新功能。调用的格式是使用“parent:方法名”在子类的重载方法中调用父类中被覆盖的方法。将上例中的代码修改一下,在子类重写的构造方法中使用“parent::__construct()”调用父类中被覆盖的构造方法,再多添加一条对子类中新扩展的成员属性初始化的代码。在子类中重写的say()方法中使用“parent::say()”调用父类中被覆盖的say()方法,再添加上输出子类成员属性的功能。代码如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
<?php class Person{ protected $name ; protected $sex ; protected $Wage ; function __construct( $name = "" , $sex = "男" , $age =1){ $this ->name = $name ; $this ->sex = $sex ; $this ->age = $age ; } //在人类中声明一个通用的说话方法,介绍一下自己 function say(){ echo "我的名字:" . $this -> name. ",性别:" . $this ->sex. ",年龄:" . $this ->age. "。<br>" ; } } //声明一个学生类,使用extends关键字扩展(继承)person类 class Student extends Person { private $school ; //在学生类中声明一个所在学校school的成员属性 //覆盖父类中的构造方法,在参数列表中添加一个学校属性,用来创建对象并初始化成员属性 function __construct( $name = "" , $sex = "男" , $age =1, $school = "" ){ //调用父类中被覆盖的构造方法,为从父类中集成过来额出行赋初值 parent::__construct( $name , $sex , $age ); $this ->school = $school ; } function study(){ echo $this ->name. "正在" . $this ->school. "学习<br>" ; } //定义一个和父类中同名的方法,将父类中的说话方法覆盖并重写,多说出所在的学校名称 function say(){ parent::say(); //调用父类中被本方法覆盖掉的方法 echo "在" . $this ->school. "学校上学<br>" ; } } $student = new Student( "张三" , "男" ,20, "edu" ); //创建一个学生对象,并传给一个学校名称参数 $student -> say(); //调用学生类中覆盖父类的说话方法 ?> |
上面的例子输出的结果和前一个例子是一样的,但在本例中通过在子类中直接调用父类中被覆盖的方法要简便很多。另外,在子类覆盖父类的方法时一定要注意,在子类中重写的方法访问权限一定不能低于父类被覆盖的方法的访问权限。例如,如果父类中的访问权限是protected,那么在子类中重写的方法的权限就要是protected或public。
子类重载父类的方法“parent:方法名”的更多相关文章
- 子类重载父类的方法“parent::方法名”转于 恩聪PHP学习教程
在PHP中不能定义重名的函数,也包括不能再同一个类中定义重名的方法,所以也就没有方法重载.单在子类中可以定义和父类重名的方法,因为父类的方法已经在子类中存在,这样在子类中就可以把从父类中继承过来的方法 ...
- Python子类调用父类内属性的方法
常见的就是初始化方法__init__() python中类的初始化方法是__init__(),因此父类子类的初始化方法都是这个,如果子类不实现这个函数,初始化时调用父类的初始化函数,如果子类实现这个函 ...
- java怎么调用子类中父类被覆盖的方法
public class b { { void show() { System.out.println("b"); } } public class c extends b { v ...
- javascript练习-子类调用父类的构造函数和方法
function NonNullSet(){ Set.apply(this,arguments); } NonNullSet.prototype = inherit(Set.prototype); N ...
- [Go] 子类 调用 父类 的 属性、方法
package main import ( "fmt" ) type A struct { Text string Name string } func (a *A) Say() ...
- python 子类继承父类属性及实例化方法
- c++子类和父类成员函数重名
子类和父类返回值参数相同,函数名相同,有virtual关键字,则由对象的类型决定调用哪个函数. 子类和父类只要函数名相同,没有virtual关键字,则子类的对象没有办法调用到父类的同名函数,父类的同名 ...
- python之子类继承父类时进行初始化的一些问题
直接看代码: class Person: def __init__(self): self.name = "jack" class Student(Person): def __i ...
- Golang 中的 面向对象: 方法, 类, 方法继承, 接口, 多态的简单描述与实现
前言: Golang 相似与C语言, 基础语法与C基本一致,除了广受争议的 左花括号 必须与代码同行的问题, 别的基本差不多; 学会了C, 基本上万变不离其宗, 现在的高级语言身上都能看到C的影子; ...
随机推荐
- Xcode-Xcode 7.3 解决不能自动联想问题-备
一.问题: 升级Xcode 7.3 之后发现导入头文件之后,没法自动联想. 二. 解决办法: 打开Xcode --> Target --> BuildSettings --> App ...
- 解读 《2014 最流行编程语言》 by Code Eval
此文已转至http://cn.abnerchou.me/2014/02/23/fa87ae80/ 原文:点我 原文翻译:点我 首先了解下CodeEval是做什么的: A tool for auto e ...
- 如何让多个Activity共用一个Menu
我们可以定义一个自己的CommActivity继承自Activity,然后让每个自定义Activity继承CommActivity,就可以做到. 例如: public class CommActivi ...
- ViewPager+Fragment的结合使用,实现QQ界面的理解
http://www.cssxt.com/html/2449/2449.html 效果如图: 实现代码解析:MainActivity.java1.引入布局文件2.4个标题控件的初始化以及点击事件的监听 ...
- Altium 9中正确的差分对走线方法
1.在原理图中定义差分对在菜单中Place>>Directive为差分网络放置差分对指令.差分对网络名称必须以“_N”和“_P”作为后辍.对差分网络放置指令后要对其参数进行配置,包括Dif ...
- Linux系统编程(34)—— socket编程之TCP服务器与客户端的交互
前面几篇中实现的client每次运行只能从命令行读取一个字符串发给服务器,再从服务器收回来,现在我们把它改成交互式的,不断从终端接受用户输入并和server交互. /* client.c */ #in ...
- SDL音频播放
gcc -o tutorial03 tutorial03.c -lavutil -lavformat -lavcodec -lz -lm \`sdl-config --cflags --libs` A ...
- js中iframe的用法
最近遇到的项目总是习惯左边一个树,点击每个树的节点右边出现相应的信息,遇到这种情况用iframe还是很简单的, 例如 : 页面文件 @section Tree{ <ul id="tre ...
- 寻找第K小元素
要在一个序列里找出第K小元素,可以用排序算法,然后再找.可以证明,排序算法的上界为O(nlogn). 在这里,给出两种可以在线性时间内找出第K小元素的方法. 方法1: (1) 选定一个比较小的阈值(如 ...
- markdown转dokuwiki
markdown markdown格式变得越来越通用,很多博客,云笔记,github等等都支持markdown编写,markdown也能很方便的转化为pdf,html等格式.公司的文档用的dokuwi ...