我有以下问题:
我有一个扩展A类的B类。 类A具有方法M,其具有第一参数p1(必需)和第二参数p2(可选)。 p2具有默认值V. B覆盖方法M,因此它的签名与A' s相同。
我真的很担心某些开发人员在A上的p2(V)默认值发生了变化,而这些开发人员并没有想象它会被子类覆盖而且会在他的M签名上重复使用V.
那么可以在A的子类上创建M而不重复V作为默认值,但保持行为吗?
class A
{
public function M($p1, $p2 = 'V')
{
}
}
class B extends A
{
public function M($p1, $p2 = null)
{
//do something more
return parent::M($p1, $p2);
/*
if user don't pass $p2, it will be null and will pass null to A::M too.
Is not what I want. I would like A::M get his $p2 default value 'V'.
*/
}
}
答案 0 :(得分:1)
首先,我想说,不“信任”开发人员以正确的方式使用代码可能有点奇怪。
但是我有一个建议,因为你控制了父类A
,你可以在实现中添加一些逻辑,如果V
被传递则只使用值null
。
class A {
public function M($p1, $p2 = 'V') {
if ($p2 === null) $p2 = 'V';
}
}
答案 1 :(得分:1)
非常好的PHP函数func_get_args
<?php
function aa($a, $b = null) {
var_export([$a, $b, func_get_args()]);
}
aa('1 argument');
aa('second NULL', null);
在第一种情况下,它只返回1个元素数组,因此您可以检测它是默认值还是传递值。
答案 2 :(得分:0)
在$p2
中声明A
的类型。然后它不会接受空值。
class A
{
public function M($p1, string $p2 = 'V')
{
}
}
子类中的M
方法仍然可以具有null
默认值,这很好。人们应能够在扩展课程时更改默认值。他们可以根据需要更改M
方法的整个行为。但如果它在没有分配字符串的情况下调用parent::M($p1, $p2);
,则会出现类型错误。您需要处理的情况是您的代码意外发生的事情。