我已经定义了一个抽象类和一个应该返回模板文件名称的方法。用户对这个抽象类进行子类化并实现该方法以返回模板文件名。但问题是,如果用户没有返回任何信息,则不会发出警告或任何事情。我可以强制抽象类的方法返回一些东西吗?
我怎么能确定这一点?调用此方法的代码属于框架,所以我可以用settype($returnVal, 'string')
做一些奇特的事情,如果有帮助的话?有更好的解决方案吗?
我已经定义了一个抽象类和一个应该返回模板文件名称的方法。用户对这个抽象类进行子类化并实现该方法以返回模板文件名。但问题是,如果用户没有返回任何信息,则不会发出警告或任何事情。我可以强制抽象类的方法返回一些东西吗?
我怎么能确定这一点?调用此方法的代码属于框架,所以我可以用settype($returnVal, 'string')
做一些奇特的事情,如果有帮助的话?有更好的解决方案吗?
在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
的实例,所以会抛出异常。
据我所知,没有办法在PHP中实现返回值的类型提示。自PHP 5以来,function parameters的提示有限。
但即使有,你想要做的不是一个类型暗示的工作。如果我返回的字符串是空的,会发生什么?无论调用哪个方法,您都需要检查返回值,并做出适当的反应。
我能想到的唯一办法做到这一点是建立在调用代码将使用父类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或更高版本中使用。
不是真的,但它不回答关于抽象方法,因为php7.1 – 2017-05-19 08:47:58
在PHP 7也能够强制方法像这样返回一个类的实例:
class MyClass
{
public function getData(): MyData
{
return 1234; //TypeError!
}
}
class MyData
{
}
以这种方式,下面的代码是无效的,并抛出一个TypeError
:
$obj = new MyClass();
$obj->getData();
这也可以在抽象方法中完成:abstract public function getData():MyData; – 2017-05-19 08:47:22
好,但它可以检查返回值,对不对? – openfrog 2009-12-27 10:48:07
@openfrog:是的,当然 - 但你必须自己编码:它不是由PHP强制执行的(我在编辑你的评论时编辑了我的答案 - 我将再次编辑一个例子) – 2009-12-27 10:50:57
这很棒。谢谢!!你实际上一次回答我的两个问题:-) – openfrog 2009-12-27 10:55:05