开发者学堂课程【PHP 进阶教程-由浅入深掌握面向对象开发-第二阶段:接口继承】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/712/detail/12709
接口继承
内容介绍:
一、概念
二、示例
三、小结
一、概念
接口继承本质就是接口可以被接口继承。
1.接口继承的目的
(1)实现接口的成员扩展:丰富接口内容,从而实现更好的对实现类的规范。在上层的接口可以只规范基础的类,到了实施和具体的项目组就可以再做更细的规范。在基于原来的接口情况下,不可能修改原代码,继承已有的实现,同时再做更多的实现,丰富接口内容。丰富的目的是让实现变得更好,后面的类在实现接口时能完善得更多,做得更完美。
(2)为了形成完成的接口体系,让不同级别的类实现不同级别的接口。接口有架构在,但是有的类只需要完成基础的业务就可以满足,那就可以实现高级别的高层接口,而有的类需要实现的模块比较大,就需要实现更多的业务,就应该实现低级别的接口。
接口可以一次性继承多个接口。
接口继承的过程中不单只可以实现一个接口继承,还可以实现多个接口继承。
举例:
interface A{}
interface B{}
#接口继承
interface C extends A{}
#接口多继承
其中 interface A 和 interface B 是两个独立的接口,interface C 要继承接口使用 extends 关键字继承接口 A,C 就拥有了接口里面的内容,同时可以再自己扩展内容。而多接口继承是直接在继承时用逗号分隔不同的接口名字,就同时拥有了接口 A 和 B 里面所有的规范内容。
二、示例
1.数据库设计规范:使用接口
(1)为了规范所有数据库表的操作,设定接口方法:所有的数据库操作都必须使用规定的接口。
想要设计数据库规范接口,用接口来做,一个团队可能有很多,可能有不同的团队做不同产品的实现,如果随便取名,每个团队的名字都不一样,就意味着以后代码需要切换不同数据库时会非常费劲,需要修改原代码,所以在这种项目架构下应该用接口来规范。需要做一个顶层的接口,接口是用来规范所有的数据库的类,最终操纵数据库都需要使用这四个方法
interface DB{
public function insert(string $sq1);
public function update(string $sq1);
public function delete(string $sq1);
public function select(string $sq1);
增删改查。
考虑到操作的便捷性,需要使用到自动新增、自动查询、自动修改,因此增加一个下级接口,继承原有接口。
这只是规范,并没有实现,所以接下来要考虑有的团队拿到后认为使用粗糙,开发效率低,因为所有的编程人员都需要先写好 SQL,此时需要快捷的方式使其自动生成。考虑到操作的便捷性,需要使用到自动新增、自动查询、自动修改,但是也必须要用到此接口,因为自动新增了语句,最终还是要调用增删改查,实现同样的目的。因此增加一个下级接口,继承原有接口。
interface AutoDB extends DB{
public function autoInsert(array $data,int $id) ;
public function autoupdate(array $data,int $id);
public function autoselect(array $condition) ;
}
此时实现了接口的继承,因此 AutoDB 里除了上述四个被继承来的方法,还有三个,自己内部的接口规范 autoInsert、autoupdate、autoselect。这样在项目组里用接口继承实现了接口内容的丰富,有的项目也可以没有。
·封装数据库操作类:实现接口(基础数据库类,实现基础操作)
在没有这层规范的项目组里,就可以直接实现 DB
class SQL implements DB{
public function _constructO){
#初始化数据库连接认证、字符集、数据库选择
}
public function insert(string $sq1){
#实现新增
}
public function update(string $sq1){
#实现更新
}
public function delete(string $sq1){
#实现删除
}
public function select(string $sq1){
#实现查询
}
构造方法完成初始化然后实现各个方法。以后调用 SQL 类对象就可以用这些方法来实现数据库的增删改查,但是必须要提供完整的 SQL 指令。
业务数据库操作类:继承数据库操作类 SQL 并实现便捷业务操作
class Mode1 extends soL implements AutODB{
#初始化操作已经由 SQL 完成,只需要实现 AutoDB 的自动操作
public function autoInsert(array $data,int $id){
#实现自动构造新增 SQL 指令,调用父类的 insert 方法实现
}
public function autoupdate(array $data,int $id){
#实现自动构造更新 SQL 指令,调用父类的 update 方法实现
}
public function autoselect(array $condition){
#实现自动构造查询 SQL 指令,调用父类的 select 方法实现
}
}
因为 mode 类最终还要被更细的业务调用,所以在继承类的时候,同时去实现接口 AutoDB。AutoDB 里面有七个方法要实现,因为它继承了 DB 接口。七个里面已经实现了 SQL 类的四个,只需要完成后三个的实现就可以,实现之后整个接口体系就完成了。以后想要直接使用简单的继承 SQL 类,直接调用方法就可以完成,这种通常比较麻烦,系统难以自动生成,如果有容易生成的,比如新增、更新和查看,就可以继承 mode 类,然后调用方法来实现。这样只要有数组和 ID 就可以实现自动新增,如果没有 ID 可以把 ID 置为不存在的东西,不用 ID 作为条件。此处加了 ID 是考虑到 ID 可以做到自动存在。更新需要 ID,而查询只需要条件数组。
把架构放到代码里体现:
借口架构使用首先有一个顶级接口,顶级接口只是做初级规范,完全有必要的才进行接口规范。此时访问接口不应该有问题。
有的团队为了更细化更好的规范下面团队的实现,可以做子接口,此时需要单继承。
interface AutoDB extends DB{
public function autoInsert(array $data,int $id);
public function autoUpdate(array $data,int $id);
public function autoSelect(array $condition);
}
此时要实现这个接口,就必须实现以上七个方法。再来实现:
这是简单实现接口,也就是实现初级接口。
简单实现接口就是说只实现初级接口,因为只有四个方法,所以只要完成这四个方法就可以,但是此时接口里所有的方法都要实现。意味着 SQL 类可以直接被别人调用实现数据库的操作,此时还是一个较为初级的操作,SQL 针对的是关系型数据库。如果不够可以在实现的过程中再来丰富实现其他的接口。class mode 继承的一定是类,implements 实现的一定是接口。
这是类的继承外加额外接口的实现,目的是丰富操作内容。
这里只实现了三个方法,还有四个是继承的 SQL 所以前面已经做好了。在有的地方不允许 SQL 直接实例化,就把它变为抽象类,因为 SQL 针对太多产品,语法有可能不一样,所以一个来实现可能不够,所以需要把层级再拔高,抽象类来实现接口,子类来实现抽象类,用继承的方式实现。这种架构可以理解为接口到类的层级规范,接口规范在大型项目里可以用这种方式体现出来。
2.生物设计规范:使用接口
(1)人类是一类特定生物,设计一个接口
所有的人类都必须用接口来实现,里面规范了人类必须要有行走和说话这两项功能。
interface Human{
public function waTk();
public function talk();
}
(2)动物是大类特定生物,设计一个接口
interface Animal{
public function eat();
public function drink();
}
(3)人猿是一类生物既有人类的基本特性又有动物的基本特性:因此继承两个接口,并且扩展一个睡觉的接口。
interface Ape extends Human,Animal{
public function sleep();
}
·实现具体的人猿操作
所有跟猿相关的类必须要实现 Ape 接口,实现里面的五个方法。
class Monkey implements Ape{
public function walk(){}
public function talk(){}
public function eat(){}
public function drink(){}
public function sleep(){}
}
这种接口体系中用到了多继承。
顶级接口不同的业务有不同的接口,不可能所有都规范一起,接口也是分类的。
#顶级接口
interface Human{
public function walk();
public function talk();
}
interface Animal{
public function eat();
public function drink();
}
#有物种有以上两种特性(为了方便不能使一个类实现多个对应接口,可以继承,也可以是空接口,主要是为了类的实现方便。)
interface Ape extends Human,Animal{
public function sleep();
}
#所有 APE 相关类应该实现 Ape 接口(需要实现五个接口系统才不会报错)
cLass Monkey implements Ape{
public function walk(){}
public function talk(){}
public function eat(){}
public function drink(){}
public function sleep(){}
}
这样就利用继承和丰富让结构变得更加复杂,复杂的上层规定使下层实现变得单一。
三、小结
1、接口可以继承接口,而且可以多继承
2、接口是在更大型的项目中,为了保证底层的实现而设定的规范,通常是抽象类实现接口,增加必要成员,然后让实际业务类去继承抽象类。可以再增加抽象,再增加数据的规范或提供基础要求,对象的类必须要有基础数据,这样可以做得更加细致得实现架构。
3、类在继承其他类的时候可以同时去实现相应接口,不要求父类与接口有任何关系(可以有关系)。比如上面的例子是在继承类的同时还实现了额外的接口,这个接口与它本身有关系所以才能简化只实现三个方法,如果类没有实现接口 DB,意味着需要实现七个接口。





