接口或类中的PHP类构造函数

ran*_*zer 12 php oop interface class

我有一些问题想出一个好的结构来构建我的类和对象.在下面的代码中,我使用一个接口来定义我的类方法,但我也想将数据库连接传递给我的构造函数,以便类具有此连接.这是正确的,因为我在下面编码它的构造函数放在我的类和我的界面中的方法?

interface IDataItem
{
    public function saveItem(Item $theItem);
}

class DataItem implements IDataItem
{
    public function __construct(Database $database) 
    { 
        $this->database = $database;
    }

    public function saveItem(Item $item) 
    {       
        //save the item
    }
}

$db = new Database(); //from a database class
$dataItem = new DataItem($db);          
$dataItem->saveItem($anItem);
Run Code Online (Sandbox Code Playgroud)

Gor*_*don 16

虽然在技术上可以将构造函数添加到接口,但接口不应该定义构造函数,因为这将是实现类的实现细节.接口应该只定义其他协作者可以调用的公共API.也就是说,他们不应该强制执行特定的实现.

如果您在接口中放置了一个构造函数请求数据库连接,那么您将具体类限制为构造函数签名中的依赖项.如果实现接口的具体类需要不同(因为它保存到Web服务)或其他(可能是Logger)依赖项,则无法使用您的接口.


fd8*_*8s0 10

我个人认为你不应该把构造函数放在接口中,因为你永远不会通过调用构造函数来创建一个新对象而不知道你正在使用哪个实现.

你的代码中有一个错误,接口中的方法不能有实现,它只需要一个声明,就像这样

interface IDataItem
{
    public function saveItem($theItem);
}
Run Code Online (Sandbox Code Playgroud)


Jon*_*lka 6

这有点偏离主题,但是我认为它着重说明了在接口中定义构造函数可能有用的情况。

可以在不知道其类的情况下实例化该对象。这是一个简单的示例:

interface Animal
{
    public function __construct($name);
    public function speak();
    public function getName();
}

class Cat implements Animal
{
    protected $name=null;
    public function __construct($name){ $this->name=$name; }
    public function speak(){ echo 'meow'; }
    public function getName(){ return $this->name;}
}

class Dog implements Animal
{
    protected $name=null;
    public function __construct($name){ $this->name=$name; }
    public function speak(){ echo 'woof'; }
    public function getName(){ return $this->name;}
}

$animals=Array(array('name'=>'Felix','type'=>'Cat'),array('name'=>'Fido','type'=>'Dog'));

foreach($animals as $a)
{
    $theAnimal=new $a['type']($a['name']);
    echo '<p>speak, '.$theAnimal->getName().'</p><p>';
    $theAnimal->speak();
    echo '</p>';
}
Run Code Online (Sandbox Code Playgroud)

我已经使用了类似的方法进行URL路由,以将URL与其顶级控制器匹配。


oma*_*ari 6

根据 PHP 文档:

“请注意,可以在接口中声明构造函数,这在某些情况下很有用,例如供工厂使用。”

要点是构造函数不必用具体的类定义,而是可以用接口定义,例如:

interface TestInterface {
    public function __construct(interfaceA, interfaceB);
}
Run Code Online (Sandbox Code Playgroud)

然后,实现 TestInterface 的类使用接口 A 和接口 B 的具体实现来定义其构造函数:

class Test implements TestInterface {
    public function __construct(testA, testB);
}
Run Code Online (Sandbox Code Playgroud)

其中 testA 可能类似于:

class testA implements interfaceA {
    public function doStuff() {
        //...
    }
}
Run Code Online (Sandbox Code Playgroud)