在 PHP 中,如果在父类中定义了静态属性,则不能在子类中覆盖它。但我想知道是否有任何方法可以解决这个问题。
我正在尝试为其他人的(有些笨拙的)函数编写一个包装器。有问题的函数可以应用于许多不同的数据类型,但每个数据类型需要不同的标志和选项。但在 99% 的情况下,每种类型的默认值就足够了。
如果这可以通过继承来完成,而不必每次都编写新函数,那就太好了。例如:
class Foo {
public static $default = 'DEFAULT';
public static function doSomething ($param = FALSE ) {
$param = ($param === FALSE) ? self::$default : $param;
return $param;
}
}
class Bar extends Foo {
public static $default = 'NEW DEFAULT FOR CHILD CLASS';
}
echo Foo::doSomething() . "\n";
// echoes 'DEFAULT'
echo Bar::doSomething() . "\n";
// echoes 'DEFAULT' not 'NEW DEFAULT FOR CHILD CLASS'
// because it references $default in the parent class :(
最佳答案
实际上我认为这不是真的:您可以覆盖静态属性(您需要 >=5.3 PHP)。但是在引用该静态属性时必须小心(这是原始代码中的错误)
您需要使用 static::$myStaticProperty 而不是使用 self::$myStaticProperty
self:: 将引用 当前类,因此如果您在继承的静态方法中,这将引用定义该方法的该类的静态属性!使用引用关键字时 static::会像 $this - 当您使用实例方法/属性时。
在您的示例中,doSomething() 是类 Bar 中的继承静态方法。由于您在那里使用了 self::,它将引用类 Foo 的静态属性。这就是为什么您没有看到任何差异的原因... 尝试将 self::更改为 static::!
这是一个代码示例 - 我自己用它来测试这些东西。我们有静态属性/方法继承、覆盖和值更改 - 运行它,您将看到结果!
class A {
// a static property - we will test override with it
protected static $var = 'class A var - override';
// a static property - we will test value overwrite with it
protected static $var2 = 'class A var2 - value overwrite';
public static function myStaticOverridePropertyTest() {
return static::$var;
}
public static function myStaticValueOverwritePropertyTest() {
return static::$var2;
}
/**
* This method is defined only here - class B will inherit this one!
* We use it to test the difference btw self:: and static::
*
* @return string
*/
public static function myStaticMethodTest() {
//return self::getValue();
return static::getValue();
}
/**
* This method will be overwritten in class B
* @return string
*/
protected static function getValue() {
return 'value from class A';
}
}
class B extends A {
// we override this inherited static property
protected static $var = 'class B var - override';
/**
* This method is overwritten from class A
* @return string
*/
protected static function getValue() {
return 'value from class B';
}
/**
* We modify the value of the inherited $var2 static property
*/
public static function modStaticProperty() {
self::$var2 = 'class B - altered value! - value overwrite';
}
}
echo ("-- testing class A:\n");
echo (A::myStaticOverridePropertyTest(). "\n");
echo (A::myStaticValueOverwritePropertyTest(). "\n");
echo (A::myStaticMethodTest(). "\n");
echo ("-- now testing class B:\n");
echo (B::myStaticOverridePropertyTest(). "\n");
echo (B::myStaticValueOverwritePropertyTest(). "\n");
echo (" now invoking B::modStaticProperty() .\n");
B::modStaticProperty();
echo (B::myStaticValueOverwritePropertyTest(). "\n");
echo ("-- now re-testing class A:\n");
echo (A::myStaticOverridePropertyTest(). "\n");
echo (A::myStaticValueOverwritePropertyTest(). "\n");
echo (A::myStaticMethodTest(). "\n");
这将输出:
-- 测试A类:
A 类 var - 覆盖
A 类 var2 - 值覆盖
A类的值
-- 现在测试 B 类:
B 类 var - 覆盖
A 类 var2 - 值覆盖
现在调用 B::modStaticProperty() ...
B 级 - 改变的值(value)! - 值覆盖
-- 现在重新测试A类:
A 类 var - 覆盖
B 级 - 改变值(value)! - 值覆盖
A类的值
在这里,您可以看到覆盖静态属性和仅值覆盖静态属性之间的区别......看看我用粗体标记的输出行!当我们调用 B 类的 modStaticProperty() 时,它也改变了 A 类中该静态变量的值。由于该静态属性是继承的并且没有被覆盖!想一想……
关于php - PHP中静态成员的继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/532754/