PHP中的接口是否应该返回相同的类型? 我的朋友告诉我它应该返回相同的类型。(为了良好的做法) 我知道PHP是动态类型语言,它是不可能的。
例如:
interface idReturn
{
//Return INT
public function getById($id);
}
interface arrayReturn
{
//Return array
public function getByData($data);
}
这是好的做法吗?
答案 0 :(得分:5)
这不是界面的事情。为避免在使用者中进行类型检查,方法应仅返回一种类型。由于reduced number of execution pathes through the code,因此更容易理解代码。
例如,这增加了不必要的复杂性:
function get_users()
{
// some code returning array when users have been found
// or null when no users have been found
}
$users = get_users();
if (!is_null($users)) {
foreach ($users as $user) {
// do something with $user
}
}
如果get_users()
在没有找到用户时只返回一个空数组,则可以简化消费代码只需阅读
foreach (get_users() as $user) {
// do something with $user
}
此外,凭借Liskov's Substitution Principle,任何超类型子类的类都需要在使用超类型的消费者中互换使用。如果消费者需要一个整数,您可能不会返回一个字符串,因为这可能会破坏消费者。对于实现该接口的接口和使用者的类,例如
,情况也是如此interface Contract
{
/** @return array */
public function fn();
}
现在假设A implements Contract
并返回数组,而B implements Contract
并返回数组或null。当B返回null时,我的消费者期望数组现在会中断:
function fn(Contract $instance)
{
// will break when B returns null
foreach ($instance->fn() as $foo) {
// do something with $foo
}
}
由于PHP目前无法强制执行返回类型,因此由开发人员在DocBlock中指示它并确保实现或子类型类符合该返回类型。
话虽如此,如果合同定义了多种可能的退货类型,消费者必须确保它能够处理它们。但是,这又意味着不合需要的类型检查。
答案 1 :(得分:3)
他可能是这个意思:
interface I {
public function f();
}
class A implements I {
public function f() {
return 1; // int
}
}
class B implements I {
public function f() {
return 'a'; // string
}
}
您是否想要这完全取决于您为I::f
定义的合同。合同应该放在单独的文档中,因为PHP缺乏对正式指定它们的支持(这不是特定于PHP的,大多数语言都是这种情况,D和Eiffel都是明显的例外)。