在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。

 

>> 本文固定链接: http://php.ncong.com/php_course/oop/reload_parent.html

>> 转载请注明: 恩聪php 2014年07月24日 于 恩聪PHP学习教程 发表

子类重载父类的方法“parent:方法名”的更多相关文章

  1. 子类重载父类的方法“parent::方法名”转于 恩聪PHP学习教程

    在PHP中不能定义重名的函数,也包括不能再同一个类中定义重名的方法,所以也就没有方法重载.单在子类中可以定义和父类重名的方法,因为父类的方法已经在子类中存在,这样在子类中就可以把从父类中继承过来的方法 ...

  2. Python子类调用父类内属性的方法

    常见的就是初始化方法__init__() python中类的初始化方法是__init__(),因此父类子类的初始化方法都是这个,如果子类不实现这个函数,初始化时调用父类的初始化函数,如果子类实现这个函 ...

  3. java怎么调用子类中父类被覆盖的方法

    public class b { { void show() { System.out.println("b"); } } public class c extends b { v ...

  4. javascript练习-子类调用父类的构造函数和方法

    function NonNullSet(){ Set.apply(this,arguments); } NonNullSet.prototype = inherit(Set.prototype); N ...

  5. [Go] 子类 调用 父类 的 属性、方法

    package main import ( "fmt" ) type A struct { Text string Name string } func (a *A) Say() ...

  6. python 子类继承父类属性及实例化方法

  7. c++子类和父类成员函数重名

    子类和父类返回值参数相同,函数名相同,有virtual关键字,则由对象的类型决定调用哪个函数. 子类和父类只要函数名相同,没有virtual关键字,则子类的对象没有办法调用到父类的同名函数,父类的同名 ...

  8. python之子类继承父类时进行初始化的一些问题

    直接看代码: class Person: def __init__(self): self.name = "jack" class Student(Person): def __i ...

  9. Golang 中的 面向对象: 方法, 类, 方法继承, 接口, 多态的简单描述与实现

    前言: Golang 相似与C语言, 基础语法与C基本一致,除了广受争议的 左花括号 必须与代码同行的问题, 别的基本差不多; 学会了C, 基本上万变不离其宗, 现在的高级语言身上都能看到C的影子; ...

随机推荐

  1. DotNET知识点总结三(笔记整合)

    使用接口的注意事项: 接口中的成员不能加访问修饰符 接口中的成员不能有任何实现 实现接口的子类必须实现接口的全部成员 一个类可以同时继承一个类并实现多个接口,如果一个子类同时继承了父类A,并实现了接口 ...

  2. Altium Designer 蛇行等长布线

    一. 设置需要等长的网络组 点击主菜单 Design --> Classes,在弹出的窗口中单击 Net Classes,并右键,点 Add Class 会增加一个 New Class,在该网络 ...

  3. Qt自定义带游标的slider,在滑块正上方显示当前值(类似于进度条,用一个额外的QLabel冒充QSilder的一部分,然后move就行了)

    首先自定义QSlider的子类MyCustomSlider,如下所示. mycustomslider.h #ifndef MYCUSTOMSLIDER_H #define MYCUSTOMSLIDER ...

  4. MSSQL 标准PROC 写法

    MSSQL 标准PROC 写法 ALTER PROC [dbo].[usp_ADM_InsertFlowSortInfo]@FlowSortName NVARCHAR(50),AS/*PAGE: 分类 ...

  5. A - Network of Schools - poj 1236(求连通分量)

    题意:学校有一些单向网络,现在需要传一些文件,1,求最少需要向几个学校分发文件才能让每个学校都收到,2,需要添加几条网络才能在任意一个学校分发都可以传遍所有学校. 分析:首先应该求出来连通分量,进行缩 ...

  6. 你需要知道的九大排序算法【Python实现】之基数排序

    八.基数排序 基本思想:基数排序(radix sort)属于"分配式排序"(distribution sort),又称"桶子法"(bucket sort)或bi ...

  7. [Redux] React Todo List Example (Adding a Todo)

    Learn how to create a React todo list application using the reducers we wrote before. /** * A reduce ...

  8. 学习设计模式--观察者模式(C++)

    1. 说说简单的函数回调 首先说说一种简单的函数回调机制(一种通过获取对象的指针来进行函数的调用方法)以下是代码演示--- 这是观察者(被回调)部分: class Observer { public: ...

  9. Windows下用Caffe跑自己的数据(遥感影像)

    1 前言 Caffe对于像我这样的初学者来说是一款非常容易上手的深度学习框架.关于用Caffe跑自己的数据这样的博客已经非常多,感谢前辈们为我们提供的这么好的学习资源.这里我主要结合我所在的行业,说下 ...

  10. this关键字之一个有趣的用法

    this关键字 1.首先一个用处就是代表当前类的对象. 2.当我们对构造函数进行重载的时候代码如下: public class Class1 { public string Name { get; s ...