nblogs-markdown">
title: PHP类的多态与封装
date: 2018-6-21
categories:
PHP学习笔记
tags:php
多态性(Polymorphism),简单的说就是同一操作作用于不同的类的实例上时,会产生不同的执行结果。
在软件设计中,多态使得应用程序更加模块化和可扩展。
多态性分两种:
静态多态性:指一个同名函数或者一个类中的同名方法,根据参数列表(类型及个数)的不同来区别语义,即所谓的函数重载。但PHP不支持函数重载。
动态多态性:指类的成员方法,能根据调用它的对象类型的不同,自动做出适应性调整,而且调整时发生在程序运行时。(PHP通过抽象类和接口技术来实现动态多态性)
子类覆盖父类
子类对继承自父类的方法进行“重写”,就是子类中定义一个同名的父类方法。
覆盖后若要使用父类原来的方法,需要使用关键字parent
和 域操作符::
parent::父类同名方法;
如果父类“很强势”,不想自己的方法别子类覆盖重写,可以使用final
关键字来修饰该方法。
抽象类和抽象方法
抽象类是一种不能被实例化的类,只能作为父类被其他类继承。
与其他类一样抽象类也可以有属性和方法,但不同点在于,抽象类必须至少包含一个抽象方法。
所谓抽象方法,就是没有具体实现的方法,其对应的函数体为空。
抽象方法的细节只能在子类中实现,而且子类必须实现所继承的抽象类中的所有的抽象方法。
抽象类和抽象方法都用关键字abstract
来定义,格式如下:
abstract class 抽象类名{ //... abstract [public | protected] function 抽象方法名 ([方法参数]); //定义抽象方法 }
其中,抽象方法的访问控制修饰符只能是 public 或 protected 。
如果抽象方法声明为 public ,则子类中实现的方法也应声明为 public ;
如果抽象方法声明为 protected ,则子类中实现的方法既可以声明为 protected,也可以声明为 public。
抽象方法和抽象类的作用:
抽象方法和抽象类主要用于设计复杂的层次关系,这种层次关系要求子类都包含并重写某个特定的方法。
例如,人按社会分工可以分为学生、工人、商人等,每个人都要工作,只是岗位不同,学生要在学校听课,工人要在工地干活,商人要在店铺卖东西等。
如果把人作为一个抽象类,工作作为抽象方法,把学生、工人、商人作为继承该类的子类,那么工作这个方法在子类中的实现细节是不同的。
abstract class 人类{ //抽象类,不能被实例化,只能作为父类被其他类继承 //... abstract function 工作(); //抽象方法,只定义没有具体内容 } class 学生 extends 人类{ //继承了人类这个抽象类,就必须实现人类中所有的抽象方法 function 工作(){ 写作业 } } class 工人 extends 人类{ //继承了人类这个抽象类,就必须实现人类中所有的抽象方法 function 工作(){ 干活 } }
接口
接口是一种多态技术。无论是普通类还是抽象类,都只能实现单继承,即一个子类只能继承一个父类。而要继承多个类就要通过接口(interface)来实现。
接口也可以看着是一种类,
只是这种类中可以定义常量,当不能定义属性变量;
可以定义方法,但方法必须为空,且方法必须为 public (可以省略,因为类的方法默认就是 public)
接口通过关键字 interface 来定义,格式如下:
interface 接口名{ const 常量名 = 值;//只能定义常量,不能定义变量 ... function 方法名([参数]); //只定义,没有具体内容 }
子类通过 implements 关键字来实现接口,格式如下:
class 子类名 implements 接口名{ //子类实现细节 }
子类可以实现多个接口,接口名之间用逗号“,”连接。格式如下:
class 子类名 implements 接口名1, 接口名2, 接口名3{ //子类实现细节 }
子类在实现接口时,必须实现接口中所有的方法。
思考:接口和抽象类抽象方法有什么异同点?
答:
相同点:
接口和抽象类中的方法都是定义而没有具体内容。
均只能作为父类被其他类继承。
子类均要实现抽象方法或接口中的所有方法。
接口 interface --- 子类 implements
抽象类 abstract --- 子类 ententds
不同点:
子类只能继承一个抽象类(子类只能单继承),子类可以有多个接口(可以看成多个父类)。
接口中只能定义常量而不能定义变量,而抽象类可以。