接口中的构造函数方法是不是很糟糕?
答案 0 :(得分:39)
为什么人们认为有人想要实例化界面?
我们想做的是强制实现者实现构造函数,就像其他接口方法一样。
界面就像合约。假设我有一个接口Queue,我想确保实现者创建一个带有一个参数的构造函数,它创建一个单例队列(一个只有该元素的新队列)。为什么不应该成为合同的一部分?至少使用Java接口,无法指定。
答案 1 :(得分:12)
他们不好,因为他们没有任何目的。从本质上讲,接口只是一个数据传递合同。没有任何实现附加接口,因此没有任何内容可以初始化,也不需要构造函数。
如果你需要某种初始化,你最好使用抽象类。
答案 2 :(得分:7)
首先,我不同意接口只是一个数据传递合同。如果确实如此,您将被允许在界面中定义属性。
我不会认为这样做很奇怪:
interface IDBConnection
{
function __construct( $connectionString );
function executeNonQuery( $commandText, $paramters=null);
function executeScalar( $commandText, $paramters=null);
function executeSingle( $commandText, $paramters=null);
function executeArray( $commandText, $paramters=null);
}
这将使您能够基于简单反射而不仅仅是数据协定来创建用于数据访问的第三方类的实例。
我很确定这不是最好的例子,我会在现实世界中找到一个抽象基类,但我也很确定定义构造函数方法有充分合理的理由'在我没有想到的界面中签订合同。
我没有看到它完成,但我不认为它是奇怪或坏。
答案 3 :(得分:4)
虽然接口在大多数语言中都不能有构造函数,但Factory pattern提供了构造对象的契约,类似于接口。看看那个。
答案 4 :(得分:2)
无论它们是否坏,我都不知道任何语言能够在接口上指定构造函数。
尽管如此,我个人并不认为对象的构造函数是该对象接口的一部分,因此向接口添加构造函数会抑制接口提供的自然灵活性。
答案 5 :(得分:0)
您有时必须通过需要参数的构造函数实例化不可变的多态对象,并且出于与在接口中需要其他公共方法的完全相同的原因,您可能需要在接口中使用该构造函数,例如……
假设您必须实例化一个多态对象,该类实现您的接口并由客户端代码提供。作为一种愚蠢但简单的方案,我们可以说该对象是一个值对象,因此应该是不可变的,这意味着该对象的状态从实例化那一刻起就应该是有效的……
$immutablePolymorphe = $userConfig['immutable_polymorphe_class'];
$immutablePolymorphe = new $immutablePolymorphe($state);
// Then do something with that polymorphe...
那么,如果您没有在接口中定义带有其参数的构造函数怎么办?因此,我之所以相信接口中的构造函数与接口中任何其他公共方法一样合法的原因……
答案 6 :(得分:0)
我不知道谷歌为什么把我送到这里:)
但是这个问题很有趣,我在很多项目中看到有人在接口中定义了构造函数。但我真的认为这是一个无用的限制。此类的任何客户端都不能调用 __construct
。
并且在接口中定义它不限制任何行为,我仍然可以按照我的意愿实现它,我什至可以有一个空函数,例如:
...
function __construct(string $name) {}
...
那有什么好处呢?它只会阻止您进行多态性,而没有任何好处。
如果你有:
<?php
interface Shape {
function __construct(int $width, int $height);
public function getArea();
}
class Square implements Shape {
public function __construct(int $width, int $height) {...}
public function getArea(){...}
}
// This will throw an exception because it does not implement the correct constructor signature!
class Circle implements Shape {
public function __construct($radius) {...}
public function getArea(){...}
}
即使你想扩展 Square,你也必须实现相同的构造函数!
答案中有一个例子:
<块引用>你必须实例化不可变的多态对象...
示例如下:
$immutablePolymorphe = $userConfig['immutable_polymorphe_class'];
$immutablePolymorphe = new $immutablePolymorphe($state);
// Then do something with that polymorphe...
这是聪明的想法,但前提是您可以将 $userConfig
数组中的字符串限制为特定接口!至少据我所知,这是不可能的。
所以最重要的是 :D 我认为在界面中使用 __construct
是不好的,它会阻止你改进你的软件,它会鼓励你有不好的解决方法。