我是一名自学成才的程序员,目前我正在学习Zend Framework 2。
我总是想知道为什么每次当我试图包含某项服务时,他们总是要求我使用它的界面版本。
例如,如果我正在尝试使用Service Locator,我将必须包含serviceLocatorInterface才能使用Service Locator。为什么我不能只使用Service Locator类本身。
这是来自Abstract Factory类。
use Zend\ServiceManager\ServiceLocatorInterface;
然后我会用这种方式使用它
public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName)
use Blog\Service\PostServiceInterface;
我们包括PostServiceInterface。为什么不只是PostService?
public function __construct(PostServiceInterface $postService)
我们在这里使用PostServiceInterface。为什么不将PostService作为类型。
我相信这是一个非常简单的答案,所有学生都可以回答,但因为我自己也在学习,所以我很难理解它。
PS。我理解接口和继承的概念。我只是不知道为什么我们这样包含接口。
编辑:在答案之后我找到了一个链接,帮助我更好地理解为什么人们将接口作为类型依赖而不是具体类型传递。
What is the difference between an interface and abstract class?
http://kristopherwilson.com/2015/03/26/using-interfaces-effectively-in-php/
我希望这些链接也可以帮助别人。
qazxsw poi创建使用的类完全限定名称的本地别名。类名不仅仅是类的名称,它始终包含定义它的名称空间。
如果你不使用use
关键字创建一个本地别名,php假设,该类在当前命名空间中(如果你没有在文件中声明一个命名空间,那么这是根命名空间use
)
一个简单的例子
\
请注意,// 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
。创建一个继承自PostService
的新类可能不是一个好的解决方案(甚至不可能,因为PostService可以声明为PostService
)
他们的出路是:不要使用类,使用接口作为参数。这个原则是final
原则的一部分,命名为SOLID并陈述两件事: