考虑以下代码:
interface MotorInterface
{
public function start();
}
class Car
{
private $motor;
public function __construct(MotorInterface $motor)
{
$this->motor = $motor;
}
public function start() {
return $this->motor->fire();
}
}
我对接口作为依赖项注入时的工作方式感到困惑。您可能已经注意到,我已经将MotorInterface
接口作为依赖项传递给Car
类。该接口仅指定一个原型。但现在考虑一下:
class PetrolMotor implements MotorInterface
{
public function start() {
return 'starting';
}
public function fire() {
return 'firing';
}
}
这..
$motor = new PetrolMotor();
$car = new Car($motor);
var_dump($car->start());
它可以工作并显示firing
。但是,我从未在fire()
中原型化MotorInterface
方法。如何运作?
答案 0 :(得分:2)
PHP并不限制您可以在对象上调用的方法。
引用PHP Manual on Type Declarations:
类型声明允许函数在调用时要求参数为某种类型。
您注入了PetrolMotor
的{{1}}。这将满足类型提示。这就是类型提示所做的全部。从技术上讲,它不限制以后可以以任何方式在对象上调用的方法。您的MotorInterface
具有PetrolMotor
方法,因此尽管界面中没有fire()
仍可以调用它。
但是,类型提示确实会影响大多数IDE中的自省,这将抱怨该方法在接口中不可用。
答案 1 :(得分:0)
将接口视为项目的工作规范,它是代码的一部分,以便能够以最基本的形式“工作”。
例如,对于用户而言,您真正需要做的第一件事是最主要的事情;登录,因此,我们可以这样看待它;
<?php
interface iUser
{
function login($uname, $pword);
}
这为用户类必须具备的基本规则设定了规定,为此,我们可以创建实现该类的类;
class User implements iUser
{
public function login($uname, $pword)
{
/* code to login */
}
}
现在,这并不意味着您可能不需要界面之外的更多功能,因为它在那里不相关,但是在您的类中,例如,您可以具有如下所示的onLoginCreateSession ...
class User implements iUser
{
public function login($uname, $pword)
{
/* code to login */
onLoginCreateSession($uname); // Call this here in the event of successful login
}
private function onLoginCreateSession($uname)
{
/* set session variables for login success */
}
}
接口背后的主要理由是,允许类的基本规则集相似,但具有不同的工作集来实现某些目标;例如,
<?php
interface iCRUD
{
public function create (array $data);
public function read($recordid);
public function update(array $data);
public function delete($recordid);
}
这是一个简单的界面,具有4个函数定义,但是当我们实现它时...
class User implements iCrud
{
public function create (array $data)
{
// create to a user table using data
}
public function read($recordid)
{
// read from a user table using id
}
public function update(array $data)
{
// update user table based on data
}
public function delete($recordid)
{
// delete from user table using id
}
}
class Documents implements iCRUD
{
public function create (array $data)
{
// create to a documents table using data
}
public function read($recordid)
{
// read from a documents table using id
}
public function update(array $data)
{
// update documents table based on data
}
public function delete($recordid)
{
// delete from documents table using id
}
}
您可以看到同一界面如何用于多种解决方案