PHP的抽象类和接口
抽象类与接口相似,都是一种比较特殊的类。抽象类是一种特殊的类,而接口也是一种特殊的抽象类。它们通常配合面向对象的多态性一起使用。虽然声明和使用都比较容易,但它们的作用在理解上会困难一点。
①抽象类
在OOP语言中,一个类可以有一个或多个子类,而每个类都有至少一个公有方法作为外部代码访问它的接口。而抽象方法就是为了方便继承而引入的。本节中先来介绍一下抽象类和抽象方法的声明,然后再说明其用途。在声明抽象类之前,我们先了解一下什么是抽象方法。抽象方法就是没有方法体的方法,所谓没有方法体是指在方法声明时没有花括号及其中的内容,而是在声明方法时直接在方法名后加上分号结束。另外在声明抽象方法时,还要使用关键字abstract来修饰。声明抽象方法的格式如下所示:
abstract function fun1(); //不能有花括号,就更不能有方法体中的内容了
abstract function fun2(); //直接在方法名的括号后面加上分号结束,还要使用abstract修饰
只要在声明类时有一个方法时抽象方法,那么这个类就是抽象类,抽象类也要使用abstract关键字来修饰。在抽象类中可以有不是抽象的成员方法和成员属性,但访问权限不能使用private关键字修饰为私有的。下面的例子在Person类中声明了两个抽象方法say()和eat(),则Person类就是一个抽象类,需要使用abstract标识。代码如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<?php abstract class Person{ protected $name ; protected $country ; function __construct( $name = "" , $country = "china" ){ $this ->name = $name ; $this ->country = $country ; } abstract function say(); abstract function eat(); function run(){ echo "使用两条腿走路<br>" ; } } ?> |
在上例中声明了一个抽象类Person,在这个类中定义了两个成员属性、一个构造方法和两个抽象方法,还有一个是非抽象的方法。抽象类就像是一个“半成品”的类,在抽象类中有没有被实现的抽象方法,所以抽象类是不能被实例化的,即创建不了对象,也就不能直接使用它。既然抽象类是一个“半成品”的类,那么使用抽象类有什么作用呢?使用抽象类就包含了继承关系,它是为它的子类定义公共接口,将它的操作(可能是部分,也可能是全部)交给子类去实现。就是将抽象类作为子类重载的模板使用,定义抽象类就相当于定义了一种规范,这种规范要求子类去遵守。当子类继承抽象类以后,就必须把抽象类中的抽象方法按照子类自己的需要去实现。子类必须把父类中的抽象方法全部都实现,否则子类中还存在抽象方法,所以还是抽象类,也不能实例化对象。在下例中声明了两个类,分别实现上例中声明的抽象类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
|
<?php class ChineseMan extends Person{ function say(){ echo $this ->name. "是" . $this ->country. "人,讲汉语<br>" ; } function eat(){ echo $this ->name. "使用筷子吃饭<br>" ; } } class Americans extends Person{ function say(){ echo $this ->name. "是" . $this ->country. "人,讲英语<br>" ; } function eat(){ echo $this ->name. "使用刀子和叉子吃饭<br>" ; } } $chianeseMan = new ChineseMan( "高洛峰" , "中国" ); $americans = new Americans ( "alex" , "美国" ); $chineseMan ->say(); $chineseMan ->eat(); $americans ->say(); $americans ->eat(); ?> |
在上例中声明了两个类去继承抽象类Person,并将Person类中的抽象方法按各自的需求分别实现,这样两个子类就都可以创建对象了。抽象类Person就可以看成是一个模板,类中的抽象方法自己不去实现,只是规范了子类中必须要有父类中声明的抽象方法,而且要按照自己的特点实现抽象方法的内容。
②接口技术
因为PHP只支持单继承,也就是说每个类只能继承一个父类。当声明的新类继承抽象类实现模板以后,它就不能再有其他父类了。为了解决这个问题,PHP引入了接口。接口是一种特殊的抽象类,而抽象类又是一种特殊的类。如果抽象类中的所有方法都是抽象方法,我们就可以换另外一种声明方式,使用“接口”技术。接口中声明的方法必须都是抽象方法,另外不能再接口中声明变量,只能使用const关键字声明为常量的成员属性,而且接口中所有成员都必须有public的访问权限。类的声明是使用“class”关键字标识的,而接口的声明则是使用“interface”关键字标识的。声明接口的格式如下所示:
1
2
3
4
5
6
|
<?php interface 接口名称{ //使用interface关键字声明接口 常量成员 //接口中的成员属性只能是常量,不能是变量 抽象方法 //接口中的所有方法必须是抽象方法,不能有非抽象的方法存在 } ?> |
接口中的所有方法都要求是抽象方法,所以就不需要在方法前使用abstract关键字标识了。而且在接口中也不需要显式地使用public访问权限进行修饰,因为默认权限就是public的,也只能是公有的。另外接口和抽象类一样也不能实例化对象,它是一种更严格的规范,也需要通过子类来实现。但可以直接使用接口名称在接口外面去获取常量成员的值。一个接口的声明例子,代码如下所示:
1
2
3
4
5
6
7
|
<?php interface one{ const CONSTANT = 'CONSTANT value' ; function fun1(); function fun2(); } ?> |
也可以使用extends关键字让一个接口去继承另一个接口,实现接口之间的扩展。在下面的例子中声明一个Two接口继承了上例中的One接口。代码如下所示:
1
2
3
4
5
6
|
<?php interface Two extends one{ function fun3(); function fun4(); } ?> |
如果需要使用接口中的成员,则需要通过子类去实现接口中的全部抽象方法,然后创建子类的对象去调用在子类中实现后的方法。但通过类去继承接口时需要使用implements关键字来实现,而并不是使用extends关键字完成。如果需要使用抽象类去实现接口中的部分方法,也需要使用implements关键字实现。在下面的例子中声明一个抽象类Three去实现One接口中的部分方法,但要想实例化对象,这个抽象类还需要有子类把它所有的抽象方法都实现才行。声明一个Four类去实现One接口中全部方法。代码如下所示:
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
|
<?php interface one{ const CONSTANT = 'CONSTANT value' ; function fun1(); function fun2(); } //声明一个抽象类去实现接口One中的第二个方法 abstract class Three implements One{ //只实现接口中的一个抽象方法 function fun2(){ //具体的实现内容由子类自己决定 } } //声明一个类实现接口One中的全部抽象方法 class Four implements One{ function fun1(){ //具体的实现内容由子类自己决定 } function fun2(){ //具体的实现内容由子类自己决定 } } ?> |
PHP是单继承的,一个类只能有一个父类,但是一个类可以实现多个接口。将要实现的多个接口之间使用逗号分隔开,而且在子类中药将所有接口中的抽象方法全部实现才可以创建对象。就相当于一个类要遵守多个规范,就像我们不仅要遵守国家的法律,如果是在学校,还需要遵守学校的校规一样。实现多个接口的格式如下所示:
class 类名 implements 接口一,接口二,……接口n{
实现所有接口中的抽象方法
}
实现多个接口是使用“implements”关键字,同时还可以使用“extends”关键字继承一个类。即在继承类的同时实现多个接口,但一定更要先使用extends继承一个类,再去使用inplements实现多个接口。使用格式如下所示:
class 类名 extends 父类名 implements 接口一,接口二,……接口n{
实现所有接口中的抽象方法
}
除了上述的一些应用外,还有很多地方可以使用使用接口,例如对于一些已经开发好的系统,在结构上进行较大的调整已经不太现实,这时可以通过自定义一些接口并追加相应的实现来完成功能结构的扩展。
PHP的抽象类和接口的更多相关文章
- 抽象类 VS 接口
引言 接口和抽象类是面向对象编程(OOP, Object Oriented programming)中两个绕不开的概念,二者相似而又有所不同.接下来,我们来了解二者的概念并比较它们的异同. 什么是抽象 ...
- java抽象类和接口
面向对象设计过程中重要的一点是如何进行抽象,即把"问题空间"中的元素与"方案空间"中的元素建立理想的一对一的映射关系.抽象类和接口便是抽象过程中的产物. ...
- php中抽象类与接口的概念以及区别
php里面的接口类,抽象类到底有什么用呢? 刚接触php的时候,觉得这个东西没什么用,其实这些东西还是有一定的作用的,下面我就简单的说说. 1.php 接口类:interface 其实他们的作用很简单 ...
- Java 抽象类与接口
接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法. 抽象类与接口是 Java 语言中对抽象概念进行定义的两种机制,正是由于他们的存在才赋予 Java 强大的面向对象的能力.他们两者之间对 ...
- 浅谈我对C#中抽象类与接口的理解
C#中的抽象类与接口有些相似,初学者很容易混淆,今天就让我来谈谈对二者的理解. 首先我们得明确二者的含义,分述如下: 如果一个类不与具体的事物相联系,而只是表达一种抽象的概念,仅仅是作为其派生类的一个 ...
- Atitit 深入理解抽象类与接口 attilax总结
Atitit 深入理解抽象类与接口 attilax总结 1.1. 主要区别接口侧重于动作抽象..抽象类是属性名词抽象..1 1.2. 抽象层次类>>抽象类>>接口1 1.3. ...
- luogg_java学习_07_抽象类_接口_多态学习总结
这篇博客总结了半天,希望自己以后返回来看的时候理解更深刻,也希望可以起到帮助初学者的作用. 转载请注明 出自 : luogg的博客园 , 抽象 一种专门用来做父类,被继承的. (模板) 格式: abs ...
- PHP中抽象类,接口定义
这里先介绍接口,因为在我最近看的好几本php工具书中都没有提到抽象类. 本人也觉得,在理解了接口后抽象类也非常好理解. 例子代码随便写了一下.例子代码是很ok的,测试过了不会报错,懒得看代码的筒靴们看 ...
- 0026 Java学习笔记-面向对象-抽象类、接口
抽象方法与抽象类 抽象方法用abstract修饰,没有方法体部分,连花括号都不能有: 抽象方法和抽象类都用abstract修饰 包含抽象方法的类一定是抽象类:但不包含抽象方法的类也可以是抽象类 不能创 ...
- Java抽象类与接口的区别
很多常见的面试题都会出诸如抽象类和接口有什么区别,什么情况下会使用抽象类和什么情况你会使用接口这样的问题.本文我们将仔细讨论这些话题. 在讨论它们之间的不同点之前,我们先看看抽象类.接口各自的特性. ...
随机推荐
- 【HDOJ】2772 Matchsticks
纯粹的找规律题.1: 22: 53: 54: 45: 56: 67: 38: 79: 60: 6 2 1 13 7 74 4 115 2 ...
- java容器类总结
1.java容器分类图 说明:左图为简化图(其中粗线部分是重点的容器),右图为完整容器分类图 2.容器类接口和抽象容器类 2.1 说明 容器接口是容器 ...
- word页面不对齐,如何解决?
http://blog.163.com/haibianfeng_yr/blog/static/34572620201157105439516/
- 关于开发板不能ping通外网IP
最近在做远程监控的项目,打算用开发板给一个网站发送数据包.不过发现开发板只能ping通同一局域网内的ip,外网的ip不能ping通.纠结了半天发现是网关没有设置的原因.下面来说说如何解决这个问题. 首 ...
- 利用Jenkins自动部署工具间接构建kettle的调度平台
关于Jenkins的介绍我就不说了,自己百度,因为这个工具调用脚本只是他的功能的冰山一角,其他功能我也不能理解,因为不是那个领域. 下面我就介绍一下为什么我们需要一个调度平台,以及学习完 ...
- hadoop1.X安装
1. 配置主机的名称 master,slave1,slave2 2. 安装JDK: 3. 配置IP与主机名称的映射: 192.168.0.100 master 192.1 ...
- 百练2755 奇妙的口袋 【深搜】or【动规】or【普通递归】or【递推】
总Time Limit: 10000ms Memory Limit: 65536kB 有一个奇妙的口袋.总的容积是40,用这个口袋能够变出一些物品,这些物品的整体积必须是40.John如今有n个 ...
- Linux crontab 命令详解(含配置文件路径)
编辑/etc/crontab 文件配置cron cron 服务每分钟不仅要读一次/var/spool/cron内的所有文件,还需要读一次/etc/crontab,因此我们配置这个文件也能运用cron服 ...
- Oracle按用户进行统计信息更新
按用户进行统计信息更新 PL/sqldev工具使用system用户连接到oracle,打开命令窗口执行以下SQL,用户名请根据实际情况进行更改: begin dbms_stats.gather_sch ...
- 人工智能2:智能Agent
一.Agent基本定义 基于理性行为的Agent是本书人工智能方法的核心.Agent由传感器.执行器两个重要元件组成,具有与环境交互的能力,其能力是通过分析感知序列,经过Agent函数映射到相应的行动 ...