gpt4 book ai didi

php - 为什么PHP中的 "use"关键字需要和Interface一起使用?

转载 作者:行者123 更新时间:2023-12-04 16:55:46 24 4
gpt4 key购买 nike

我是一名自学成才的程序员,目前正在学习 Zend Framework 2。

我总是想知道为什么每次当我尝试包含某个服务时,他们总是要求我使用它的 Interface 版本。

例如,如果我尝试使用 Service Locator,则必须包含 serviceLocatorInterface 才能使用 Service Locator。
为什么我不能只使用 Service Locator 类本身。

这是来自抽象工厂类。

use Zend\ServiceManager\ServiceLocatorInterface;

然后我会以这种方式使用它
public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName)

这是 Zend 教程中的另一个示例, https://framework.zend.com/manual/2.4/en/in-depth-guide/services-and-servicemanager.html#bringing-the-service-into-the-controller
use Blog\Service\PostServiceInterface;

我们包括 PostServiceInterface。为什么不只是 PostService?
public function __construct(PostServiceInterface $postService)

我们在这里使用 PostServiceInterface。为什么不只是 PostService 作为类型。

我相信这是一个非常简单的答案,所有学生都可以回答,但由于我自己正在学习这个,所以我很难理解它。

附注。我确实理解接口(interface)和继承的概念。我只是不知道为什么我们以这种方式包含 Interface。

编辑:在回答之后,我找到了一个链接,可以帮助我更好地理解为什么人们将接口(interface)作为类型依赖而不是具体类型传递。

What is the difference between an interface and abstract class?

http://kristopherwilson.com/2015/03/26/using-interfaces-effectively-in-php/

我希望这些链接对其他人也有帮助。

最佳答案

use创建所用类的全限定名的本地别名。类名不仅仅是类的名称,它始终包含定义它的 namespace 。

如果您不使用 use关键字来创建本地别名,php 假设,该类在当前命名空间中(如果你没有在文件中声明命名空间,这是根命名空间 \ )

一个简单的例子

// the current namespace
namespace Foo;

use Test\ClassName;

class Bar {
public function __construct(Baz $a) {
// Baz isn't a full qualified class name (missing leading \), so
// php assumes, Baz is inside the current namespace Foo
// => full class name is \Foo\Baz;
}

public function doSomething(ClassName $a) {
// ClassName isn't a full qualified class name, BUT there is an use
// statement, which imported ClassName to the local file
// => \Test\ClassName
}

public function doSomethingElse(\ClassName $a) {
// ClassName IS a full qualifed class name
// => \ClassName
}
}

请注意, \ClassName\Test\ClassName是两个不同的类。

那么为什么要使用 PostServiceInterface而不是 PostService
您不必这样做,但这样做有很多好处,这是一个很好的做法。 IE。您想稍后测试该功能并且没有 PostService .创建一个新类,它继承自 PostService don 可能不是一个好的解决方案(甚至不可能,因为 PostService 可以声明为 final )

他们的出路是:不要使用类,使用接口(interface)作为参数。这个原则是 SOLID的一部分原则,命名 Dependency Inversion Principle并声明两件事:
  • 高级模块不应该依赖于低级模块。两者都应该依赖于抽象。
  • 抽象不应该依赖于细节。细节应该取决于抽象。
  • 关于php - 为什么PHP中的 "use"关键字需要和Interface一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43644372/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com