【发布时间】:2015-12-13 17:58:29
【问题描述】:
根据 php.net 文档:
从抽象类继承时,所有在父类声明中标记为抽象的方法都必须由子类定义;此外,这些方法必须定义为具有相同(或较少限制)的可见性。例如,如果抽象方法定义为受保护,则函数实现必须定义为受保护或公共,但不能定义为私有。此外,方法的签名必须匹配,即类型提示和所需参数的数量必须相同。例如,如果子类定义了一个可选参数,而抽象方法的签名没有,则签名中没有冲突。这也适用于 PHP 5.4 的构造函数。 5.4 之前的构造函数签名可能不同。
在 php.net 中,他们展示了以下示例:
abstract class AbstractClass
{
// Force Extending class to define this method
abstract protected function getValue();
abstract protected function prefixValue($prefix);
// Common method
public function printOut() {
print $this->getValue() . "\n";
}
}
class ConcreteClass1 extends AbstractClass
{
protected function getValue() {
return "ConcreteClass1";
}
public function prefixValue($prefix) {
return "{$prefix}ConcreteClass1";
}
}
class ConcreteClass2 extends AbstractClass
{
public function getValue() {
return "ConcreteClass2";
}
public function prefixValue($prefix) {
return "{$prefix}ConcreteClass2";
}
}
$class1 = new ConcreteClass1;
$class1->printOut();
echo $class1->prefixValue('FOO_') ."\n";
$class2 = new ConcreteClass2;
$class2->printOut();
echo $class2->prefixValue('FOO_') ."\n";
如果我运行它,我会得到以下输出:
ConcreteClass1 FOO_ConcreteClass1 ConcreteClass2 FOO_ConcreteClass2
阅读文档,我最初的理解是“如果父类是扩展的,一般来说父类不能访问子类的方法”,这就是我们需要抽象类的原因。然而,当我尝试上面的相同示例并稍作调整,删除所有抽象(如下所示)时,我看到与前一个示例完全相同的输出。因此,为什么我们需要 PHP 中的抽象类。我发现的唯一用例是在父类中实现接口时;如果我没有将父级声明为抽象,我会收到错误。在其他情况下我必须或强烈建议使用抽象类吗?
//abstract
class AbstractClass
{
// Force Extending class to define this method
//abstract protected function getValue();
//abstract protected function prefixValue($prefix);
// Common method
public function printOut() {
print $this->getValue() . "\n";
}
}
class ConcreteClass1 extends AbstractClass
{
protected function getValue() {
return "ConcreteClass1";
}
public function prefixValue($prefix) {
return "{$prefix}ConcreteClass1";
}
}
class ConcreteClass2 extends AbstractClass
{
public function getValue() {
return "ConcreteClass2";
}
public function prefixValue($prefix) {
return "{$prefix}ConcreteClass2";
}
}
$class1 = new ConcreteClass1;
$class1->printOut();
echo $class1->prefixValue('FOO_') ."\n";
$class2 = new ConcreteClass2;
$class2->printOut();
echo $class2->prefixValue('FOO_') ."\n";
【问题讨论】:
标签: php