从长相上看,接口就是一个空类,只包含方法的声明。
所以任何类要实现接口,必须“完成”它里面定义的所有方法。就像一个国家的宪法,所有州县法律是基于此基本法来定义的。你也可以把接口理解成是一个严格的声明。接口有助于在扩展类时严格执行在接口中定义的所有方法。可以通过使用关键字implements来实现接口。
为什么需要接口这样的东西呢?
接口相对于一个普通类来说,使用它意味着一个严格的规范。
举个例子,我们在创建一个Web应用时,这个应用可能会和不同的数据库有连接和处理操作,可以有MySQL、Postgral SQL、MariaDB、SQLLite等。我们现在的开发团队要开发不同的数据库驱动类。
那么会是怎样的策略呢,分配给3个人,让他们按自己的风格开发?这当然没问题。但是使用这些类时必须仔细看这些类的方法和类定义,比如有人连接数据库用conn命名,有人喜欢用connect,千奇百怪,美不胜收。对于调用的人,这简直太枯燥、太折磨人,后面也很不好维护。
因此,我们需要严格定义该接口。本例给它有一个固定的名字,driver,然后有两个方法,名为connect()和execute()。实现这个接口需要严格按此规约来“实现”,调用的开发都不必再担心类或方法有变化,写接口类的开发者也可以随时优化内部方法,无须伤及应用。
下面我们创建数据库驱动driver接口类,如代码清单2-14所示:
代码清单2-14 数据库驱动接口类driver定义
<?php //interface.dbdriver.php interface DBDriver { public function connect(); //数据库连接方法 public function execute($sql); //执行SQL方法 }?>
注意到了吗?所有的方法都是空的,这是一个纯接口类。
现在,让我们创建一个MySQLDriver类,来试图实现这个接口,如代码清单2-15所示:
代码清单2-15 创建MySQLDriver类
<?php //class.mysqldriver.php include("interface.dbdriver.php"); class MySQLDriver implements DBDriver { }?>
现在,如果我们执行上面的代码,它会提供以下错误,因为MySQLDriver类中没有connect()和execute()方法的具体实现。运行此段脚本就会出现如下错误信息:
<b>Fatal error</b>: Class MySQLDriver contains 2 abstract methods and must therefore be declared abstract or implement the remaining methods (DBDriver::connect, DBDriver::execute) in <b>C:\OOP with
既然PHP已经告诉我们了,那我们就挨个方法地实现DBDriver抽象类,不能有一个遗漏,如代码清单2-16所示:
代码清单2-16 实现DBDriver接口的方法
<?php include("interface.dbdriver.php"); class MySQLDriver implements DBDriver { public function connect() { //connect to database } public function execute() { //execute the query and output result } }?>
我们尝试运行一下这个初步实现的方法。你会得到类似如下的错误信息:
<b>Fatal error</b>: Declaration of MySQLDriver::execute() must be compatible with that of DBDriver::execute() in <b>C:\ ch2\class.mysqldriver.php</b> on line <b>3</b><br />
乍一看,我们都已经实现以上相关方法,但是错误消息说execute()方法不兼容。我们再看定义的接口,会发现execute()方法应该有一个参数。所以我们实现接口类,每一个方法的结构必须与接口定义完全相同。让我们重写MySQLDriver类,如代码清单2-17所示:
代码清单2-17 完整实现的MySQLDriver类
<?php include("interface.dbdriver.php"); class MySQLDriver implements DBDriver { public $host="localhost"; public $username="username"; // specify the sever details for mysql public $database="database name"; public $myconn; public function connect() { //connect to database $conn= mysqli_connect($this->host,$this->username,$this->password); if(!$conn)// testing the connection { die ("Cannot connect to the database"); } else { $this->myconn = $conn; echo "Connection established"; } return $this->myconn; } public function execute($query) { //execute the query and output result $result = mysqli_query($conn,$query); return $result; } }?>
以上代码为相对完整的清单,我们还可以再完善接口处的方法逻辑。