【发布时间】:2008-12-12 03:47:59
【问题描述】:
我有一个基类,我想在其中指定子类必须具有的方法,但不自己实现它们。但是,子类中的方法可能与基类中的定义具有不同数量的参数。
用抽象方法尝试过,php 不允许这样做。有可能吗?
【问题讨论】:
标签: php oop abstract-class
我有一个基类,我想在其中指定子类必须具有的方法,但不自己实现它们。但是,子类中的方法可能与基类中的定义具有不同数量的参数。
用抽象方法尝试过,php 不允许这样做。有可能吗?
【问题讨论】:
标签: php oop abstract-class
子类的函数可以向签名添加额外的可选参数,而不会导致错误:
abstract class Foo {
abstract function bar($a);
}
class NewFoo extends Foo {
function bar($a, $b = null) {
//do something
}
}
【讨论】:
没有指定没有参数的抽象方法并要求子类方法通过func_get_args访问args,我不明白这怎么可能。
【讨论】:
我会说这是 PHP 面向对象的弱点之一,它不是为处理这种用例而设计的。它只是不打算允许它的重载方法
确实有可能以上述两种方式将您所说的作为一种 hack 进行:
func_get_args()
或者,只是(就像评论者提到的)传入一个参数数组。或者,您可以传入一个将您的参数作为数据成员的对象。然后你可以为你的子方法扩展参数/参数对象。
重点是 PHP 是一种以宽容而非限制为基础的语言。抽象类在 PHP 中有一个非常基本的实现。如果你需要很多这样的结构,那么 PHP 可能真的不是最好的语言选择。
【讨论】:
我不认为这是您想要在生产中使用的答案,因为它会相当慢,但为了它,我尝试使用 Reflection 编写一些东西,这似乎有效。您仍然会得到 E_STRICT,因为子类中的方法声明显然应该匹配。
class a {
protected $requiredMethodsInSubclass = array( 'method1', 'method2', 'method3' );
public function __construct() {
$reflObject = new ReflectionObject($this);
$className = $reflObject->getName();
if ($className == __CLASS__) {
//this class is being instanciated directly , so don't worry about any subclasses
return;
}
foreach ($this->requiredMethodsInSubclass as $methodName) {
try {
$reflMethod = $reflObject->getMethod($methodName);
} catch (ReflectionException $e) { //method not anywhere
trigger_error("Method $methodName is not declared in class " . __CLASS__ . " or subclass $className", E_USER_ERROR);
continue;
}
$declaringClass = $reflMethod->getDeclaringClass();
if ($declaringClass->getName() == __CLASS__) {
//method is declared in this class, not subclass
trigger_error("Method $methodName is not declared in subclass $className", E_USER_ERROR);
}
}
}
public function method1() {
}
public function method2($a) {
}
}
class b extends a {
public function __construct() {
parent::__construct();
//some stuff
}
public function method2($a, $b, $c) {
}
}
$b = new b();
【讨论】: