查询接口在PHP中的工作方式

时间:2018-06-25 09:27:15

标签: php oop

考虑以下代码:

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方法。如何运作?

2 个答案:

答案 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
    }
}

您可以看到同一界面如何用于多种解决方案