2009-12-27 30 views
6

我已经定义了一个抽象类和一个应该返回模板文件名称的方法。用户对这个抽象类进行子类化并实现该方法以返回模板文件名。但问题是,如果用户没有返回任何信息,则不会发出警告或任何事情。我可以强制抽象类的方法返回一些东西吗?

我怎么能确定这一点?调用此方法的代码属于框架,所以我可以用settype($returnVal, 'string')做一些奇特的事情,如果有帮助的话?有更好的解决方案吗?

回答

11

在PHP中,你不能“强制”一个方法来返回任何东西 - 即使对于抽象类/方法和接口来说也是不可能的。

你能做的最好的是表明,实施中应返回的东西,使用评论 - 但你不能强迫人们这样做:

/** 
* @param string $a blah blah 
* @return int The return value blah blah 
*/ 
public function my_method($a); 

当然,如果你调用这个方法(从框架的实施),您可以检查已返回什么,并抛出一个异常,如果它不符合你的预期是什么?


这里是如何这可能是一个简单的例子实施:

class ClassA { 
    /** 
    * @param string $a blah blah 
    * @return ClassB The return value blah blah 
    */ 
    public function my_method($a) { 
     echo 'blah'; 
    } 
} 

class ClassB { 
    // ... 
} 


$a = new ClassA(); 
$returned = $a->my_method(10); 
if (!$returned instanceof ClassB) { 
    throw new Exception("Should have returned an instance of ClassB !"); 
} 

在这里,由于该方法不返回ClassB的实例,所以会抛出异常。

+1

好,但它可以检查返回值,对不对? – openfrog 2009-12-27 10:48:07

+1

@openfrog:是的,当然 - 但你必须自己编码:它不是由PHP强制执行的(我在编辑你的评论时编辑了我的答案 - 我将再次编辑一个例子) – 2009-12-27 10:50:57

+0

这很棒。谢谢!!你实际上一次回答我的两个问题:-) – openfrog 2009-12-27 10:55:05

1

据我所知,没有办法在PHP中实现返回值的类型提示。自PHP 5以来,function parameters的提示有限。

但即使有,你想要做的不是一个类型暗示的工作。如果我返回的字符串是空的,会发生什么?无论调用哪个方法,您都需要检查返回值,并做出适当的反应。

4

我能想到的唯一办法做到这一点是建立在调用代码将使用父类public final方法和protected方法将由public final方法被调用。 protected方法包含该功能,而public final方法验证protected方法的返回值。

class A { 

    public final call_this($param) { 

     $return_value = $this->extend_this($param); 

     // validate $return_value 
     if($return_value == '') 
      throw new Exception("uh-oh! Don't return an empty string!"); 

     return $return_value; 

    } 

    protected extend_this($param) { 

     // default behavior 

     return $whatever; 

    } 

} 

class B extends A { 

    protected extend_this($param) { 

     // new behavior 

     return ''; //whoops! 

    } 

} 

$b = new B; 
$b->call_this("testing testing 123"); 
//exception! 

这可能是因为虽然扩展类,如果你尝试这样的事情的人有点混乱,确保它是有据可查的。

public final是一种公共方法,如果您不知道,则不能被覆盖。另外请注意,这只能在PHP 5.0.0或更高版本中使用。

+0

不是真的,但它不回答关于抽象方法,因为php7.1 – 2017-05-19 08:47:58

6

在PHP 7也能够强制方法像这样返回一个类的实例:

class MyClass 
{ 
    public function getData(): MyData 
    { 
     return 1234; //TypeError! 
    } 
} 
class MyData 
{ 
} 

以这种方式,下面的代码是无效的,并抛出一个TypeError

$obj = new MyClass(); 
$obj->getData(); 

Sandbox

+2

这也可以在抽象方法中完成:abstract public function getData():MyData; – 2017-05-19 08:47:22

相关问题