5.0 继承


5.1 继承的概念

在现实生活中,继承一般指的是子女继承父辈的财产。在程序中,继承描述的是事物之间的所属关系,通过继承可以使许多事物之间形成一种关系体系 。

例如猫和狗都属于动物,程序中便可以描述为猫和狗继承自动物。同理,波斯猫和田园猫继承自猫,而阿拉斯加和哈士奇继承自犬,这些动物之间会形成一个继承体系, 具体下图所示。

在PHP中,类的继承是指在一个现有类的基础上去构建一个新的类,构建出来的新称作子类,现有类被称作父类,子类会自动拥有父类所有可继承的属性和方法。

在程序中,如果想声明一个类继承另一个类,需要使用extends 关键字,具体语法格式如下:

 class   子类名  extends 父类名{
//类体
}

为了让初学者更好理解继承,接下来通过一个案例来介绍子类如何继承父类

例5-11

 <?php
//定义Animal类
class Animal{
public $name;
public function shout(){
echo "动物发出叫声<br>";
}
}
//定义Dog类继承自Animal类
class Dog extends Animal{
public function printName(){
echo "name=".$this->name;
}
}
$dog=new Dog();
$dog->name="阿拉斯加";
$dog->shout();
$dog->printName();
?>

运行结果

在例5-11中,Dog类通过extends关键字继承了Animal类,这样Dog类便是Animal类的子类。从运行结果不难看出。子类虽然没有定义name属性和shout()方法,但是却能访问这两个成员。这就说明,子类在继承父类的时候,会自动拥有父类的成员。

注意:在PHP中只能实现单继承,也就是说子类只能继承一个父类(是指直接继承).

5.2 重写父类方法


在继承关系中,子类会自动继承父类中定义的方法,但有时在子类中需要对继承的方法进行一些修改,即对父类的方法进行重写。需要注意的是,在子类中重写的方法需要和父类被重写的方法具有相同的方法名参数。

例程5-11中,Dog类从Animal类继承了shout()方法, 该方法在被调用时会打印“动物发出叫声”。这明显不能描述一种具体动物的叫声,Dog 类对象表示犬类。发出的叫声应该是“汪汪”。为了解决这个问题。可以在Dog类中重写父类Animal中的shout()方法。具体代码如例5-12所示。

例5-12

 <?php
//定义Animal类
class Animal{
//动物叫的方法
public function shout(){
echo "动物发出叫声";
}
}
//定义Dog类继承自Animal类
class Dog extends Animal{
//定义狗叫的方法
public function shout(){
echo '汪汪......';
}
}
$dog=new Dog();
$dog->shout();
?>

运行结果

例5-12中,定义了Dog类并且继承自Animal类在子类Dog中定又了一个shout()方法对父类的方法进行重写。从运行结果可以看出,在调用Dog类对象的shout()方法时,只会调用子类重写的该方法,并不会调用父类的shout()方法。

如果想要调用父类中被重写的方法,就需要使用parent关键字, parent关键字用于访向父类的成员。由于parent关键字引用的是一个类而不是一个对象,因此需要使用范围解析操作符(::)。接下来通过一个案例来演示如何使用patent关键字访问父类成员方法,如例5-13所示

例5-13

 <?php
//定义Animal类
class Animal{
//动物叫的方法
public function shout(){
echo "动物发出叫声";
}
}
//定义Dog类继承自Animal类
class Dog extends Animal{
//定义狗叫的方法
public function shout(){
parent::shout();//调用父类被重写的方法
echo "<br>";
echo '汪汪......';
}
}
$dog=new Dog();
$dog->shout();
?>

运行结果

例5-13中。定义了一个Dog类继承Animal类.并重写了Animal类的shout()方法。在子类Dog的shout()方法中使用 parent::shout()调用了父类被重写的方法。从运行结果可以看出,子类通过parent关键字可以成功地访问父类的成员方法。

 注意:子类方法重写父类方法时,访问权限不能小于父类方法的访问权限。例如父类的方是poblic的, 在于类中重写时只能是public的,不能声明为protected或者private. 

 5.3 fnal关键字


继承为程序编写带来了巨大的灵话性,但有时可能需要在继承的过程中保证某些类或法不技改变,此时就需要使用final关键字。fnal 关键字有“无法改变”或者“最终”的含义因此被final修饰的类和成员方法不能被修改。接下来将针对final关键字进行详细讲解。

1. final关键字修饰类
PHP中的类被final关键字修饰后,该类将不可以被继承,也就是不能够派生子类。接下来通过一个案例来验证,如例5-14所示。

例5-14

 <?php
//定义Animal类
final class Animal {
//程序代码
}
class Bird extends Animal {
//程序代码
}
$bird=new Animal();
?>

运行结果 程序发生报错

例5-14中,由于Animal类被final关键字所修饰.因此,当Bind类继承Animal类时,编译出现了   无法从最终Animal类进行继继承的错误。由此可见,被final关键字修饰的类为最终类,不能被其他类继承。

1. final关键字修饰方法

当一个类的方法被final关键字修饰后,这个类的子类不能重写该方法。接下来通过一个案例来验证,如例5-15所示。

 例5-15

  <?php
class Animal{
final public function shout(){
//方法体为空
}
}
class Bird extends Animal{
public function shout(){
//方法体为空
}
}
$bird=new Animal();
$bird->shout();
?>

程序报错,运行结果

 例5-15中,Bind类重写父类Animal 中的shout()方法后,编译报错。
这是因为Animal类的shout0方法被final 所修饰,由此可见,被final关键字修饰的方法为最终方法,子类不能对该方法进行重写(被final关键字修饰的方法子类可以继承)。
正是由于final的这种特性,当在父类中的定义某个方法时,如果不希望被子类重写,就可以使用final关键字修饰该方法。 

浅谈PHP面向对象编程(五、继承)的更多相关文章

  1. 浅谈python面向对象编程和面向过程编程的区别

    面向过程:分析出解决问题所需要的步骤,然后用函数把这些步骤一步步实现,使用的时候再一个个的依次调用即可. 优点:性能高 缺点:相较于面向对象而言,不易维护,不易复用,不易扩展 适合于小型的项目面向对象 ...

  2. 浅谈PHP面向对象编程(二、基础知识)

    和一些面向对象的语言有所不同,PHP并不是一种纯面向对象的语言,包PIP它支持面向对象的程序设计,并可以用于开发大型的商业程序.因此学好面向对象输程对PHP程序员来说也是至关重要的.本章并针对面向对象 ...

  3. 浅谈PHP面向对象编程(一、简介)

    传统的面向过程 将要完成的工作,分作若干个步骤,或再细分为子步骤,然后后步骤从前往后一步一步完成,最初达致目标. 现代的面向对象 将要完成的工作拆分为“一个一个对象”的任务(功能),每个对象独自完成自 ...

  4. 浅谈PHP面向对象编程(九、设计模式)

    9.0 设计模式 在编写程序时经常会遇到一此典型的问题或需要完成某种特定需求,设计模式就是针对这些问题和需求,在大量的实践中总结和理论化之后优选的代码结构编程风格,以及解决问题的思考方式. 设计模式就 ...

  5. 浅谈PHP面向对象编程(七、抽象类与接口)

    7.0 抽象类与接口 当定义一个类时,常常需要定义一些方法来描述该类的行为特征.但有时这些方法的实现方式是无法确定的,此时就可以使用抽象类和接口. 抽象类和接口用于提高程序的灵活性.抽象类是一种特殊的 ...

  6. 浅谈PHP面向对象编程(六、自动加载及魔术方法)

    6.0 自动加载及魔术方法  6.1 自动加载 在PHP开发过程中,如果希望从外部引入一个class.通常会使用incluae和requre方法把定义这个class的文件包含进来.但是,在大型的开发项 ...

  7. 浅谈PHP面向对象编程(八、多态)

    8.0  多态 在设计一个成员方法时,通常希望该方法具备一定的通用性.例如要实现一个动物叫的方法,由于每个动物的叫声是不同的,因此可以在方法中接收-个动物类型的参数的对象当传人猫类对象时就发出猫类的叫 ...

  8. 浅谈PHP面向对象编程(四、类常量和静态成员)

    4.0 类常量和静态成员 通过上几篇博客我们了解到,类在实例化对象时,该对象中的成员只被当前对象所有.如果希望在类中定义的成员被所有实例共享. 此时可以使用类常量或静态成员来实现,接下来将针对类常量和 ...

  9. 浅谈PHP面向对象编程(三、构造方法和析构方法)

    3.0 构造方法和析构方法 从我之前的博客可以发现,实例化一个类的对象后,如果要为这个对象的属性赋值,需要直接访问该对象的属性.如果想要在实例化对象的同时就为这个对象的属性进行赋值,则可以通过构造方法 ...

随机推荐

  1. dubbo 之filter使用

    1.继承接口com.alibaba.dubbo.rpc.Filter实现public Result invoke(Invoker<?> invoker, Invocation invoca ...

  2. 关于微信中JS-SDK的接口验证过程详细说明

    最近在做微信的企业服务号,刚开始通过个人的测试平台进行开发,使用了自定义菜单,自定义菜单包含两个功能:1.扫一扫,通过扫描我们账单的二维码,绑定账户和账单的关系:2.打开我们系统的账单查询页面,查询账 ...

  3. ubuntu16 jdk7 install&config

    1,下载jdk文件 http://www.oracle.com/technetwork/java/javase/downloads/java-archive-downloads-javase7-521 ...

  4. cocoapods导入第三方库后,xcode上import不提示,找不到第三方库的解决办法

    选择你的工程tagets, -> Build Settings -> Search Paths -> User Header Search Paths 双击User Header S ...

  5. php 路径问题

    今天迁移网站服务器时,路径出错: 解决办法: 在网站首页根目录 设置define 全局变量 ——根目录: 在涉及目录的地方,统统替换为 根目录:

  6. windows 10 安装 sql 2005 安装失败

    windows 10 安装 sql 2005 安装失败 网上的方法记录: 安装中无法启动需要先用sp4的补丁文件sqlos.dll,sqlservr.exe 替换D:\Program Files (x ...

  7. Swift GCD

    var queue: dispatch_queue_t = dispatch_get_main_queue()// 主线程 queue = dispatch_get_global_queue(DISP ...

  8. HDU1800 hash+去前导0

    注意一:卡map的时间,但是好好写+运气还是可以卡过,哇...求人品爆发 注意二:去前导0,毕竟‘0’也有ASCII码 #include<cstdio> #include<cstdl ...

  9. python正则的使用

    python的正则是通过re模块的支持 匹配的3个函数 match :只从字符串的开始与正则表达式匹配,匹配成功返回matchobject,否则返回none: re.match(pattern, st ...

  10. 【sqlite】VS2013中C#读取SQLite数据

    从“火车采集器”(免费版)中获取的网页数据,本地只能自动保存为SQLite数据,(在工具-数据转换中切换).收费版还可以用MySql.SqlServer 今天就记录一下C#读取Sqlite数据 创建一 ...