在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 :(
Run Code Online (Sandbox Code Playgroud)
Att*_*ind 33
实际上我认为这不是真的:你可以改变静态的特性(你需要> = 5.3 PHP).但是在为这个静态属性重新启动时你必须要小心(这是原始代码中的错误)
你需要使用static :: $ myStaticProperty而不是使用self :: $ myStaticProperty
self ::将refrence to current class so如果你在一个继承的静态方法中,这将引用该方法定义的那个类的静态属性!使用引用关键字static ::将像$ this一样 - 当您使用实例方法/ propeties时.
doSomething()是示例中类Bar中的继承静态方法.由于你使用self :: there,它将引用类Foo的static属性.这就是你没有看到任何区别的原因... 尝试将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");
Run Code Online (Sandbox Code Playgroud)
这将输出:
- 测试类A:
类A var - 重写
类A var2 - 值覆盖
来自类A的值
- 现在测试类B:
类B var - 重写
类A var2 - 值覆盖
现在调用B :: modStaticProperty( )......
B级 - 改变价值!- 值覆盖
- 现在重新测试类A:
类A var - 覆盖
类B - 改变了值!-
来自A类的值覆盖值
我们在这里,您可以看到覆盖和仅覆盖静态属性之间的差异...查看我用粗体标记的输出行!当我们调用类B的modStaticProperty()时,它也改变了类A中的静态变量的值.由于该静态属性是继承的并且未被覆盖!想一想......
Pau*_*xon 27
即将推出的PHP 5.3.0版本包括后期静态绑定,这可能有所帮助.使用此功能,您可以在静态方法中使用静态变量,并让后期静态绑定负责查找"正确"方法.
class Foo {
public static function getDefault() {
static $default = 'DEFAULT';
return $default;
}
public static function doSomething ($param) {
$default=static::getDefault(); // here is the late static binding
$param = ($param === FALSE) ? $default : $param;
return $param;
}
}
class Bar extends Foo {
public static function getDefault() {
static $default = 'NEW DEFAULT FOR CHILD CLASS';
return $default;
}
}
Run Code Online (Sandbox Code Playgroud)
All*_*nde 16
使用静态作为全局变量(在这种情况下是函数)的经典示例无论语言如何都是一个坏主意.
最强大的方法是创建抽象基类"Action"类的多个实现子类.
然后尝试去除实例化类的实例只是为了调用它的方法的一些烦恼,你可以将它包装在某种类型的工厂中.
例如:
abstract class AbstractAction {
public abstract function do();
}
class FooAction extends AbstractAction {
public function do() {
echo "Do Foo Action";
}
}
class BarAction extends AbstractAction {
public function do() {
echo "Do Bar Action";
}
}
Run Code Online (Sandbox Code Playgroud)
然后创建一个工厂来"辅助"实例化该功能
class ActionFactory {
public static function get($action_name) {
//... return AbstractAction instance here
}
}
Run Code Online (Sandbox Code Playgroud)
然后用它作为:
ActionFactory::get('foo')->do();
Run Code Online (Sandbox Code Playgroud)