如何在接口中使用多态?

时间:2013-04-17 18:56:53

标签: php oop inheritance polymorphism

我正在尝试实现类似于存储库模式的东西。为此,我有一个接口,所有repos实现和所有模型扩展的模型基类。

我从PHP

收到以下错误消息
  

致命错误:声明MVCBP \ Repositories \ UserRepository :: add()必须与D:\ wamp \ www \ mvc \ MVCBP中的MVCBP \ Core \ RepositoryInterface :: add(MVCBP \ Core \ Model $ model)兼容第9行的Repositories \ UserRepository.php

我想要的是我的存储库类中的方法应该根据接口接受Model的实例作为参数。但是我想在实现中键入提示特定的模型。这在PHP中可行吗?

RepositoryInterface.php

  <?php
  namespace MVCBP\Core;

  use MVCBP\Core\ModelInterface;

  interface RepositoryInterface
  {
    public function add(ModelInterface $model);
  }

UserRepository.php

<?php
namespace MVCBP\Repositories;

use MVCBP\Core\PDOMySQL;
use MVCBP\Core\RepositoryInterface;
use MVCBP\Models\User;

class UserRepository extends PDOMySQL implements RepositoryInterface
{
    public function add(User $user)
    {
        //Omitted
    }

    //Omitted
}

ModelInterface.php

<?php
namespace MVCBP\Core;

interface ModelInterface {}

user.php的

<?php
namespace MVCBP\Models;

use MVCBP\Core\ModelInterface;
use MVCBP\Core\Validate;
use MVCBP\Repositories\UserRepository;

require_once(__DIR__ . '/../lib/password.php');

class User implements ModelInterface
{
    //Omitted
}

1 个答案:

答案 0 :(得分:0)

你可以做到这一点。您必须修改UserRepository定义。您的add方法仅接受MVCBP\Core\Model个实例。

UserRepository.php

<?php
namespace MVCBP\Repositories;

use MVCBP\Core\PDOMySQL;
use MVCBP\Core\RepositoryInterface;

//There was another mistake. Your User class is in MVCBP\Models namespace;
//use MVCBP\Core\Models\User; -> wrong one
use MVCBP\Models\User; //correct one
use MVCBP\Core\Model;

class UserRepository extends PDOMySQL implements RepositoryInterface
{
    public function add(Model $user)
    {
        if (!$user instanceof User)
            throw new \Exception('Exception msg', 101); //example exception
        //Omitted
    }

    //Omitted
}

我更喜欢需要一个接口实例,即。

public function add(SomeInterface $user)
{
    if (!$user instanceof User)
       throw new \Exception('Exception msg', 101); //example exception
}

class User implements SomeInterface {
//some code
}

然后ReposituryInterface.php看起来像这样:

<?php
namespace MVCBP\Core;

use MVCBP\Core\Model;
use MVCBP\Core\SomeInterface;

interface RepositoryInterface
{
    //We must change method definition so it can take SomeInterface implementation
    public function add(SomeInterface $model);
    public function find($id);
    public function edit(Model $model);
    public function remove($id);
    public function all();
}