【问题标题】:Do interfaces just DESCRIBE what implemenations need to do?接口是否只是描述实现需要做什么?
【发布时间】:2015-02-18 02:49:32
【问题描述】:

我只是在学习 PHP 的接口,因为我以前从未真正使用过它们,但据我了解,它们只是一个接口,因为它们被称为,以维护实现它们的类的结构?

例如,如果您想为两个不同的数据库创建两个不同的类,您可以这样做:

class mysql {

    public function connect() {
        // code here
    }

    public function getData() {
        // code here
    }

}

class mongoDB {

    public function connect() {
        // code here
    }

    public function getData() {
        // code here
    }

}

...从技术上讲,这与:

interface database {

        public function connect() {

        }

        public function getData() {

        }   

}

class mysql implements database {

    public function connect() {
        // code here
    }

    public function getData() {
        // code here
    }

}

class mongoDB implements database {

    public function connect() {
        // code here
    }

    public function getData() {
        // code here
    }

}

...我说的对吗?只是使用界面可以确保您不会执行以下操作,因此无法轻松更改数据库?

class mysql {

    public function connect_mysql() {
        // code here
    }

    public function getData() {
        // code here
    }

}

class mongoDB {

    public function connect_mongo() {
        // code here
    }

    public function getData() {
        // code here
    }

}

这就是他们背后的原因吗?

【问题讨论】:

  • 你是对的。对象接口允许您创建代码来指定类必须实现哪些方法,而无需定义如何处理这些方法。
  • 非常正确,但是interfaces 函数不能有主体,所以你声明它们public function getData(); 而不是public function getData() {}
  • 是的,你明白了 :-D 请记住,一个类可以有许多不同类型的接口
  • 太好了——谢谢大家!

标签: php interface implements


【解决方案1】:

接口的作用是标准化您的代码可以依赖的内容,同时将其与特定实现分离。哇,听起来很复杂。从界面的用户的角度来说明它更容易:

function (MyDatabaseInterface $db) {
    $db->connect();
    $db->getData();
}

类型提示是使用接口的重要组成部分。这个函数声明它的参数必须是MyDatabaseInterface 的一个实例,换句话说,任何implements MyDatabaseInterface 的对象。只要是implements MyDatabaseInterface,具体对象是什么完全取决于您。并且由于在MyDatabaseInterface 中您已经指定了方法connect()getData(),因此您可以确定传入的任何对象都具有这些方法并且您可以调用它们。

反过来,看看这个函数:

/**
 * @return MyDatabaseInterface
 */
function foo() {
   ...
}

这个函数在内部做什么无关紧要,但它声明它将返回一个MyDatabaseInterface类型的对象,换句话说就是implements MyDatabaseInterface的一些对象。当您调用它时,您就知道可以依赖什么:

$bar = foo();
$bar->connect();
$bar->getData();

这个函数可能会返回mysqlmongoDB 的实例,这与您无关。您只需坚持接口中声明的内容,无论您获得什么特定对象,您的代码都将正常工作。

接口实际上定义了代码之间的接口。它定义了代码可以安全地调用其他代码的方法,而无需将细节绑定到特定类。您的特定对象可以定义比接口中定义的方法更多的方法;接口不声明类结构。一个类可以同时实现多个接口,这意味着它实现了所有接口的所有方法;然后,每个单独的接口将仅代表可以在对象上调用的所有可能方法的子集。

您应该描述可以在界面中完成的特定“任务”或“能力”,而不是“类”。如果您的接口名称以“-able”结尾,这是一个好兆头,例如Iterable。然后一个类可以实现几个接口,从而描述它“可以做”的所有事情。然后,您可以在特定点要求具有某种“能力”的函数参数,如上面的示例代码所示。这将部分代码相互隔离和解耦,从而使您的代码更加灵活、可重用和适应变化。


对于一个有用的现实世界场景,想象一个更大的开发团队正在处理一个大型项目。有几个子团队,每个子团队负责应用程序的不同部分。他们都坐下来,制定了一个总体计划。在某些时候,这些独立团队的代码需要相互交互。他们可以预先定义这些接口

  • “我需要在你的代码上调用一些方法来为我提供用户凭据。”
  • “好的,那么你需要给我一些对象,我可以从中得到 foobar。”
  • “那么在这里,我们将不得不与 Joe 的组件对话以发送 baz 数据。”
  • ...

在编写任何代码之前,他们可以定义需要在接口中相互通信的不同方法,然后开始做自己的事情。他们可以依赖尚未编写的代码,因为他们已经决定了界面的外观。他们甚至可以暂时用模拟对象代替真实代码,而乔仍在敲定他的真实代码,然后在以后用乔想出的任何东西简单地切换它。即使您只是一个人工作,所有这些技术也很有用。

【讨论】:

    猜你喜欢
    • 2019-07-24
    • 1970-01-01
    • 2014-01-02
    • 1970-01-01
    • 2015-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多