如何正确扩展和使用其他接口?

huangapple go评论78阅读模式
英文:

How to correctly extend and use other interfaces?

问题

以下是翻译好的部分:

我正在尝试为所有其他接口使用一个基础接口,如下所示:

基础接口

```php
<?php

namespace App\Repositories\Data;

interface IDataRepository
{
    public function getAll();
    public function getById($id);
    public function create($model);
    public function update($model);
    public function delete($id);
}

已实现的基础接口

<?php namespace App\Repositories\Data;

use Illuminate\Database\Eloquent\Model;

class DataRepository implements IDataRepository
{
    // class实例上的model属性
    protected $model;

    // 将model绑定到repo的构造函数
    public function __construct(Model $model)
    {
        $this->model = $model;
    }

    // 获取model的所有实例
    public function getAll()
    {
        return $this->model->all();
    }

    // 在数据库中创建新记录
    public function create($model)
    {
        return $this->model->create($model);
    }

    // 在数据库中更新记录
    public function update($model)
    {
        $record = $this->find($model.id);
        return $record->update($model);
    }

    // 从数据库中删除记录
    public function delete($id)
    {
        return $this->model->destroy($id);
    }

    // 显示具有给定id的记录
    public function getById($id)
    {
        return $this->model->findOrFail($id);
    }
}

我正在尝试在以下接口中使用基础接口

<?php

namespace App\Repositories;

use App\Repositories\Data\IDataRepository;

interface ITestRepository extends IDataRepository
{
}

实现

<?php namespace App\Repositories;

use App\Library\Classes\Test;
use Illuminate\Database\Eloquent\Model;

class TestRepository implements ITestRepository
{
}

在我的控制器中,我只是尝试调用测试仓库,以便我可以使用所有基础仓库函数:

class TestController extends Controller
{

    protected $testRepository;
    public function __construct(Test $test)
    {
        $this->testRepository = new TestRepository($test);
    }
    public function index()
    {
        $data['testData'] = $this->testRepository->getAll();
        return view('test', $data);
    }
}

但我收到以下错误:

类App\Repositories\TestRepository包含5个抽象方法,因此必须声明为抽象或实现其余方法

如果我只使用我的基础接口并传递模型,我的应用程序可以正常工作。以防止代码重复,分享我的基础接口中的函数在所有其他接口中的正确方法是什么?我感谢任何帮助。


请注意,由于您要求只返回翻译的部分,因此代码部分保持不变。如果您有任何其他问题或需要进一步的帮助,请随时告诉我。

<details>
<summary>英文:</summary>

I&#39;m trying to make use of a base interface for all my other interfaces as follows:


Base interface 

    &lt;?php
    
    namespace App\Repositories\Data;
    
    interface IDataRepository
    {
        public function getAll();
        public function getById($id);
        public function create($model);
        public function update($model);
        public function delete($id);
    }

Implemented base interface

        &lt;?php namespace App\Repositories\Data;
    
        use Illuminate\Database\Eloquent\Model;
    
        class DataRepository implements IDataRepository
        {
            // model property on class instances
            protected $model;
        
            // Constructor to bind model to repo
            public function __construct(Model $model)
            {
                $this-&gt;model = $model;
            }
        
            // Get all instances of model
            public function getAll()
            {
                return $this-&gt;model-&gt;all();
            }
        
            // create a new record in the database
            public function create($model)
            {
                return $this-&gt;model-&gt;create($model);
            }
        
            // update record in the database
            public function update($model)
            {
                $record = $this-&gt;find($model.id);
                return $record-&gt;update($model);
            }
        
            // remove record from the database
            public function delete($id)
            {
                return $this-&gt;model-&gt;destroy($id);
            }
        
            // show the record with the given id
            public function getById($id)
            {
                return $this-&gt;model-findOrFail($id);
            }
        }

The interface where i&#39;m trying to make use of the base interface 

    &lt;?php
    
    namespace App\Repositories;
    
    use App\Repositories\Data\IDataRepository;
    
    interface ITestRepository extends IDataRepository
    {
    }

implementation

    &lt;?php namespace App\Repositories;
    
    use App\Library\Classes\Test;
    use Illuminate\Database\Eloquent\Model;
    
    class TestRepository implements ITestRepository
    {
    }


In my controller i&#39;m trying to just call test repository so i can use all the base repository functions:

    class TestController extends Controller
    {
    
        protected $testRepository;
        public function __construct(Test $test)
        {
            $this-&gt;testRepository = new TestRepository($test);
        }
        public function index()
        {
            $data[&#39;testData&#39;] = $this-&gt;testRepository-&gt;getAll();
            return view(&#39;test&#39;, $data);
        }
    }

But i get the following error:

&gt; Class App\Repositories\TestRepository contains 5 abstract methods and
&gt; must therefore be declared abstract or implement the remaining methods

My application works fine if i only make use of my base interface and pass through a model. What would be the correct way to share functions from my base interface across all my other interfaces, so as to prevent code duplication? I appreciate any help.



</details>


# 答案1
**得分**: 1

我认为一个包含接口声明中所有方法的[Trait](https://www.php.net/manual/en/language.oop5.traits.php)是最佳选择。类似以下内容(逻辑不确定):

```php
namespace App\Repositories;

trait TDataRepository
{
    // 类实例上的模型属性
    protected $model;

    // 绑定模型到仓库的构造函数
    public function __construct(Model $model)
    {
        $this->model = $model;
    }

    // 获取模型的所有实例
    public function getAll()
    {
        return $this->model->all();
    }

    // 在数据库中创建新记录
    public function create($model)
    {
        return $this->model->create($model);
    }

    // 更新数据库中的记录
    public function update($model)
    {
        $record = $this->find($model.id);
        return $record->update($model);
    }

    // 从数据库中删除记录
    public function delete($id)
    {
        return $this->model->destroy($id);
    }

    // 显示具有给定ID的记录
    public function getById($id)
    {
        return $this->model-findOrFail($id);
    }
}

然后,只需将其用于具有基本接口的类:

namespace App\Repositories;

use App\Library\Classes\Test;
use Illuminate\Database\Eloquent\Model;

class TestRepository implements ITestRepository
{
    use TDataRepository;
}

还有一些其他选项:

  1. 抽象类带有基本接口的方法,但不像Trait那么灵活,
  2. 组合但您需要更改基本思想并为组合创建新实体。
英文:

I think that a Trait which will contains all methods of your interface declaration is the best choice. Something like (not sure about logic):

namespace App\Repositories;

trait TDataRepository
{
    // model property on class instances
    protected $model;

    // Constructor to bind model to repo
    public function __construct(Model $model)
    {
        $this-&gt;model = $model;
    }

    // Get all instances of model
    public function getAll()
    {
        return $this-&gt;model-&gt;all();
    }

    // create a new record in the database
    public function create($model)
    {
        return $this-&gt;model-&gt;create($model);
    }

    // update record in the database
    public function update($model)
    {
        $record = $this-&gt;find($model.id);
        return $record-&gt;update($model);
    }

    // remove record from the database
    public function delete($id)
    {
        return $this-&gt;model-&gt;destroy($id);
    }

    // show the record with the given id
    public function getById($id)
    {
        return $this-&gt;model-findOrFail($id);
    }
}

And then just use it for classes with base interface:

namespace App\Repositories;

use App\Library\Classes\Test;
use Illuminate\Database\Eloquent\Model;

class TestRepository implements ITestRepository
{
    use TDataRepository;
}

Also there are some other options:

  1. abstract class with methods for base interface but it not so flexible like trait,
  2. composition but you should change base idea and create a new entity for composition.

答案2

得分: 1

<?php

namespace App\Repositories;

use App\Interfaces\ITestRepository;

class TestRepository implements ITestRepository
{

    public function getAll()
    {
        // TODO: Implement getAll() method.
    }

    public function getById($id)
    {
        // TODO: Implement getById() method.
    }

    public function create($model)
    {
        // TODO: Implement create() method.
    }

    public function update($model)
    {
        // TODO: Implement update() method.
    }

    public function delete($id)
    {
        // TODO: Implement delete() method.
    }
}

类必须声明为抽象或实现方法 'getAll''getById''update''create''delete'
所以所有方法在接口中默认是抽象方法,你必须在这个类中定义所有方法。
英文:
&lt;?php


namespace App\Repositories;


use App\Interfaces\ITestRepository;

class TestRepository implements ITestRepository
{

public function getAll()
{
    // TODO: Implement getAll() method.
}

public function getById($id)
{
    // TODO: Implement getById() method.
}

public function create($model)
{
    // TODO: Implement create() method.
}

public function update($model)
{
    // TODO: Implement update() method.
}

public function delete($id)
{
    // TODO: Implement delete() method.
}

}

Class must be declared abstract or implement methods 'getAll', 'getById', 'update', 'create', 'delete'
So All the method is by default abstract method in interface and you have to define all method in this class.

答案3

得分: 0

TestRepository不应该实现任何接口,而应该扩展DataRepository

<?php namespace App\Repositories;

use App\Repositories\Data\DataRepository;

class TestRepository extends DataRepository
{
}

DataRepository已经包含了接口IDataRepository的实现。当你创建一个实现ITestRepository的类时,你将需要定义所有接口中的方法实现(在你的情况中,这些方法与基础接口相同)。

英文:

The class TestRepository should not implement any interface, but extend DataRepository:

&lt;?php namespace App\Repositories;

use App\Repositories\Data\DataRepository;

class TestRepository extends DataRepository
{
}

DataRepository contains already the implementation of the interface IDataRepository. When you create a class implementing ITestRepository you will have to define the implementation of all the methods in the interface (which are the same as the base interface, in your case).

huangapple
  • 本文由 发表于 2020年1月3日 16:30:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/59575318.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定