抽象类和接口都是不能被实例化的特殊类,可以在抽象类和接口中保留公共的方法,将抽象类和接口作为公共的基类。
在 PHP 中,子类只能继承自一个抽象类,却可以继承自多个接口。接口实现了 PHP 的多重继承,声明一个接口的关键词是 interface。
紧接上节《PHP抽象类》中的代码,我们也可以将 Database 定义为接口。示例代码如下:
interface Database { function connect($host,$username,$pwd,$db); function query($sql); function fetch(); function close(); function test(); }
同样,接口是需要被继承的,所以接口中定义的方法不能为私有方法或被 final 修饰。接口中定义的方法必须被子类实现,并且不能包含实体。
下面定义一个 MySQL 类继承自接口 Database,代码如下:
class mysql implements Database { protected $conn; protected $query; function connect($host,$username,$pwd,$db){ $this->conn = new mysqli($host,$username,$pwd,$db); } function query($sql){ return $this->conn->query($sql); } function fetch(){ return $this->query->fetch(); } function close(){ $this->conn->close(); } function test(){ echo 'test'; } }
在本例的接口示例中,接口中所有的方法都必须被子类实现,所以本例中子类 MySQL 要实现接口中定义的 test() 方法。
与抽象类不同的是,一个子类可继承自多个接口,如我们再定义一个接口 MysqlAdmin,代码如下:
interface MysqlAdmin{ function import(); function export(); }
这时我们实现 MySQL 类继承自接口 Database 和 MysqlAdmin,代码如下:
class mysql implements Database, MysqlAdmin { protected $conn; protected $query; function import(){ $sql = " load data local infile '/data/import.txt' into table table_name;"; $this->conn->query($sql); } function export(){ $sql = "select * from table_name into outfile 'export.txt'"; $this->conn->query($sql); } function connect($host,$username,$pwd,$db){ $this->conn = new mysqli($host,$username,$pwd,$db); } function query($sql){ return $this->conn->query($sql); } function fetch(){ return $this->query->fetch(); } function close(){ $this->conn->close(); } function test(){ echo 'test'; } }
类继承多个接口,多个接口之间用,分开,类要实现其继承的所有接口的全部方法。本例中 MySQL 类必须实现 Database 和 MysqlAdmin 这两个接口的全部方法。
除了类可以继承接口外,接口也可以继承接口。改写上面的例子,让 Database 接口继承自 MysqlAdmin 接口,代码如下:
interface MysqlAdmin{ function import(); function export(); } interface Database extends MysqlAdmin{ function connect($host,$username,$pwd,$db); function query($sql); function fetch(); function close(); function test(); }
同样,一个接口也可继承自多个接口。这样我们在定义一个继承自 Database 接口的 MySQL 类时,也要实现 Database 接口继承的父接口中的方法。