这个问题可能听起来很明显,也可能是愚蠢的。但我想弄清楚为什么我需要使用接口?我想我可以处理接口使用类的大部分事情然后使用它们的重点是什么?如果我没有接口,我可能会遇到问题,但我试图弄清楚不使用接口会导致什么问题?
接口的一个用途是它们允许我们定义行为并对实现它们的类施加限制。
另一个用途是接口作为类型工作,我可以使用接口进行类型提示,如下所示。
//Java example
public interface IPaintable{
void Paint(System.Drawing.Color color);
}
public void Paint(IPaintable item, System.Drawing.Color color){
item.Paint(color);
}
但是在PHP中还有其他任何接口用途吗?
即。使用以下代码中的接口可以获得哪些优势。
//Non interface implementation
<?php
class DBPersonProvider
{
public function getPerson($givenName, $familyName)
{
/* go to the database, get the person... */
$person = new Person();
$person->setPrefix("Mr.");
$person->setGivenName("John");
return $person;
}
}
/* I need to get person data... */
$provider = new DBPersonProvider();
$person = $provider->getPerson("John", "Doe");
echo($person->getPrefix());
echo($person->getGivenName());
?>
//Implementation with interface
<?php
interface PersonProvider
{
public function getPerson($givenName, $familyName);
}
class DBPersonProvider implements PersonProvider
{
public function getPerson($givenName, $familyName)
{
/* pretend to go to the database, get the person... */
$person = new Person();
$person->setPrefix("Mr.");
$person->setGivenName("John");
return $person;
}
}
/* I need to get person data... */
$provider = new DBPersonProvider();
$person = $provider->getPerson("John", "Doe");
echo($person->getPrefix());
echo($person->getGivenName());
?>
答案 0 :(得分:1)
我写了一个与数据库交互的好库。我使用MySQL
。当您购买我的图书馆时,您知道它是基于MySQL
的,但您可以使用SQL Server
。 我足够考虑为数据库访问创建接口。我为MySQL
提供了一个实现。现在,您可以围绕我的数据库访问接口实现自己的SQL Server
包装器,然后将其用作库中用于将移动存储更改为__construct()
的类的SQL Server
参数。
接口对于库/可重用代码编写者非常有用像我一样:)他们是必须遵守的代码契约。 你知道任何实现它们的类都会有一组与接口声明它们完全相同的函数。你也可以在PHP编译器强制执行的function(MyInterface $Object)
等函数参数中静态输入它们。级别,$Object
必须实施MyInterface
。
PS :抽象类对于其他自编代码消费开发人员来说已经足够了......
<强>更新强>:
/**
* Database Access functionality blueprint.
*/
interface IDatabaseAccess {
public function Connect();
public function Query();
public function Fetch();
}
/**
* Database Access functionality implementation for MySQL.
*/
class MySqlDatabaseAccess implements IDatabaseAccess {
public function Query(){
// do mysql stuff
}
public function Fetch(){
// do mysql stuff
}
}
/**
* Database Access functionality implementation for SQLServer.
*/
class SqlServerDatabaseAccess implements IDatabaseAccess {
public function Query(){
// do sqlserver stuff
}
public function Fetch(){
// do sqlserver stuff
}
}
/**
* Database Access consumer that's database system agnostic.
*/
class DatabaseAccessConsumer {
protected $_Provider = null;
public function __construct(IDatabaseAccess $Provider){
$this->_Provider = $Provider;
$this->_Provider->Connect();
}
public function Query(){
return $this->_Provider->Query();
}
public function Fetch(){
return $this->_Provider->Fetch();
}
}
^ 应该说明的代码。
答案 1 :(得分:1)
接口实际上提供的功能少于抽象类(你不能实现任何东西)。
但他们解决了多重继承的问题。大多数现代语言不允许类派生多个类。通过使用一个没有实现任何方法的接口,您可以确保从接口调用方法时没有歧义(因为没有实现)。
示例(语法上无效):
class A {
public foo() {
echo 'I am A and I foo';
};
public
}
class B {
public foo() {
echo 'I am B and I foo';
}
}
class C extends A, B { // invalid
public bar() {
foo(); // which one? A's or B's?
}
}
第二个例子:
class A {
public foo() {
echo 'I am A and I foo';
};
}
interface iB {
public foo();
public bar();
}
interface iC {
public foo();
public qux();
}
class D extends A implements iB, iC {
public bar() {
foo(); // no ambiguity, this is A::foo(), even if the method is also declared in the interfaces
}
public qux() {}
}
答案 2 :(得分:1)
接口只是类的蓝图 - 它们是说“如果你要用这种类做某事,它必须有这个并做到这一点。”它允许您在某种程度上控制另一个类在给定情况下至少具有/做的事情。并非每种情况都需要一个接口。接口最适用于需要对某些类的基本代码进行控制的情况,但您可能不是编写它们的人。如果您知道扩展类将具有x属性和y方法,那么您可以进行基本的未来类支持。