假设我有两个类(我在这里简化了逻辑):
class Table {
public function addRow (Row $row){
$this->row = $row;
}
// lots of code
}
class Row {
// lots of code
}
我想扩展表类来做类似的事情,所以我创建了两个新类:
class SpecialTable extends Table{
public function addRow (SpecialRow $row){
parent::addRow($row);
}
// lots of code
}
class SpecialRow extends Row{
// lots of code
}
当我尝试将SpecialRow添加到SpecialTable对象时,我会收到类似以下的警告:
PHP Strict standards: Declaration of SpecialTable::addRow() should be compatible with that of Table::addRow() in /SpecialTable.php on line XX
有人能帮我吗?这是一种糟糕的做法吗?我应该用不同的方式编码它?还是这只是一个我应该忽略的警告?
非常感谢您的建议/指导。
如果您要更改参数类型,您可能应该使用类似SpecialTable::addSpecialRow()的名称,否则SpecialTable实际上并没有扩展表,而是重载它(PHP不支持)。
根据您的简化示例,它应该是public function addRow(Row $row)
,因为您只是调用父级。根据您在该函数中对$row实际执行的操作,您可以键入hint Row
并在代码中检查它是否是SpecialRow
,或者如果不需要它的Special
,则只使用row。
确保SpecialRow从Row:扩展
class SpecialRow extends Row {
// lots of code
}
SpecialTable扩展自Table:
class SpecialTable extends Table {
// lots of code
}
如果Row
和SpecialRow
没有直接关系(其中SpecialRow
是专门的Row
,因此应该是extend Row
),则可以使用接口。PHP不支持没有一些疯狂丑陋的方法重载,所以一个替代方案可能是这样的:
接口:
interface IRow
{
// interface body
}
行类:
class Row implements IRow
{
}
class SpecialRow implements IRow
{
}
表类:
class Table
{
public function addRow(IRow $row)
{
$this->row = $row;
}
}
class SpecialTable
{
public function addRow(IRow $row)
{
$this->row = $row;
}
}
实施:
$t = new Table();
$st = new SpecialTable();
$r = new Row();
$sr = new SpecialRow();
$t->addRow($r);
$st->addRow($sr);
http://ideone.com/TsVw5
由于它不遵循PHP的标准,我称之为糟糕的做法。关键是派生类应该总是像它的祖先一样工作。因此,期望Row参数的类可以以相同的方式处理SpecialRow。你是在扩展类,而不是重载它。我建议为此添加另一个方法。