我正在尝试为我的服务类创建一个通用接口.我在使用界面的两个类时遇到了麻烦.他们共享一个名为create的方法.create method除了三个参数.我想让它成为第三个参数是可选的,这样两个类都可以使用它.
interface ServiceInterface{
public static function create($var1, $var2, $thisOneIsOptional);
}
class ServiceObject1 implements ServiceInterface{
public static function create($url, $server){
//....
}
}
class ServiceObject2 implements ServiceInterface{
public static function create($methode, $url, $id){
//....
}
}
Run Code Online (Sandbox Code Playgroud)
这不是实现接口的正确方法.
首先,接口定义了如何使用类,可选参数可以破坏这个原因.
除此之外,即使你有两个参数,它们应该有自己的含义,这个意思应该是共享的.
接口方法签名之间存在巨大差异:
public static function create($var1, $var2);
Run Code Online (Sandbox Code Playgroud)
和两个实现的方法:
public static function create($url, $server)
Run Code Online (Sandbox Code Playgroud)
和:
public static function create($methode, $url)
Run Code Online (Sandbox Code Playgroud)
此外,实现这种方式的AFAIK将引发严格的标准违规,因为您正在更改界面签名.
如果必须创建没有意义的共享接口,则没有理由共享或甚至创建接口.
在父类上或通过接口实现定义为抽象签名的方法的类必须遵循某些规则,但不必完全匹配。
这没有很好的文档记录,例如,接口的PHP文档中甚至没有提到它,但是抽象类的文档却对此有所提及:
此外,方法的签名必须匹配,即类型提示和所需参数的数量必须相同。例如,如果子类定义了一个可选参数,而抽象方法的签名没有,则签名中没有冲突。
换句话说,该方法必须能够根据签名被调用,但不能排除:
从问题上来看,这将起作用:
interface ServiceInterface{
public static function create($var1, $var2);
}
class ServiceObject1 implements ServiceInterface{
public static function create($url, $server){
//....
}
}
class ServiceObject2 implements ServiceInterface{
public static function create($methode, $url, $id = null){
//....
}
}
Run Code Online (Sandbox Code Playgroud)
在 PHP 56+ 中,您可以使用省略号运算符:
interface ServiceInterface {
public static function create(...$params);
}
class ServiceObject1 implements ServiceInterface
{
public static function create(...$params)
{
$url = $params[0];
$server = $params[1];
print "url = $url\n";
print "server = $server\n";
}
}
class ServiceObject2 implements ServiceInterface
{
public static function create(...$params)
{
$method = $params[0];
$url = $params[1];
$id = $params[1];
print "method = $method\n";
print "url = $url\n";
print "id = $id\n";
}
}
print "ServiceObject1::create\n";
ServiceObject1::create("url", "server");
print "\nServiceObject2::create\n";
ServiceObject2::create("method", "url", "id");
Run Code Online (Sandbox Code Playgroud)
输出:
ServiceObject1::create
url = url
server = server
ServiceObject2::create
method = method
url = url
id = url
Run Code Online (Sandbox Code Playgroud)
/咆哮
对于抱怨 OP 想要做什么的用户 - 虽然一般建议是这样做是个坏主意,但在很多情况下,程序实际上并不关心提前的参数是什么。一个例子是如果函数sumAll不是create.