PHP接口和抽象类继承的最佳实践?

use*_*300 10 php inheritance implementation abstract-class

在定义结构并继承Interface和/或Abstract Class时,哪一个是最佳实践?为什么?这里有两个例子:

以下是[Interface] - > [Abstract Class] - > [Class]的示例

Interface DataInterface
{
    public function __construct($connection);
    public function connected();
    public function get();
}

Abstract class BaseData implements DataInterface
{
    protected $connection;

    public function __construct($connection)
    {
        $this->connection = $connection;
    }
}


class UserData extends BaseData
{
    public function exists()
    {
        return is_connected($this->connection);
    }

    public function get()
    {
        return get_data($this->connection);
    }
}

$oUserData = new UserData(new Connection());
Run Code Online (Sandbox Code Playgroud)

这里是没有接口的[Abstract Class] - > [Class]的示例

Abstract class BaseData
{
    protected $connection;

    public function __construct($connection)
    {
        $this->connection = $connection;
    }

    abstract public function connected();
    abstract public function get();
}

class UserData extends BaseData
{
    public function exists()
    {
        return is_connected($this->connection);
    }

    public function get()
    {
        return get_data($this->connection);
    }
}

$oUserData = new UserData(new Connection());
Run Code Online (Sandbox Code Playgroud)

我目前正在创建一个小应用程序(可能会变得更大)并且对如何在开始时正确实现感到困惑.

顺便说一句,__construct()的这个声明是否在Interface中有意义?

public function __construct($connection);
Run Code Online (Sandbox Code Playgroud)

小智 9

抽象类定义了必须为抽象类的继承人实现的接口.Interface-Construct定义了一个必须由实现接口构造的类实现的接口,接口的实现不仅限于单个接口,而类继承耦合到单个(抽象)类.

PHP中的接口有意用于允许整个类接口的有限子集的类型提示.没有理由在抽象类上使用接口,因为他们的继承者实例的接收者没有使用它们(在instanceof/is_a上使用typehinting或逻辑标识).接口构造的更有价值的好处是可以用替代实现替换接口的通用实现.

在你的BaseData-Example的情况下,我建议删除抽象的想法,并使用特征和单独的接口.

trait connectionBrokerConstructor {
    protected $connection;

    public function isConnected()
    {
        return $this->connection instanceof Connection;
    }

    public function setConnection(Connection $connection)
    {
        $this->connection = $connection;
    }
}

interface connectable
{
    public function setConnection(Connection $connection);
    public function isConnected();
}

interface userDataRepositoryInterface
{
    public function get();
}

class UserData implements connectable, userDataRepositoryInterface
{
    use connectionBrokerConstructor;

    public function __construct(Connection $connect = null)
    {
        $this->setConnection($connection);
    }

    public function get()
    {
        return array('something');
    }
}
Run Code Online (Sandbox Code Playgroud)