在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 :(
Attila Wind.. 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");
这将输出:
- 测试类A:
类A var - 重写
类A var2 - 值覆盖
来自类A的值
- 现在测试类B:
类B var - 重写
类A var2 - 值覆盖
现在调用B :: modStaticProperty( )......
B级 - 改变价值!- 值覆盖
- 现在重新测试类A:
类A var - 覆盖
类B - 改变了值!-
来自A类的值覆盖值
我们在这里,您可以看到覆盖和仅覆盖静态属性之间的差异...查看我用粗体标记的输出行!当我们调用类B的modStaticProperty()时,它也改变了类A中的静态变量的值.由于该静态属性是继承的并且未被覆盖!想一想......
实际上我认为这不是真的:你可以改变静态的特性(你需要> = 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");
这将输出:
- 测试类A:
类A var - 重写
类A var2 - 值覆盖
来自类A的值
- 现在测试类B:
类B var - 重写
类A var2 - 值覆盖
现在调用B :: modStaticProperty( )......
B级 - 改变价值!- 值覆盖
- 现在重新测试类A:
类A var - 覆盖
类B - 改变了值!-
来自A类的值覆盖值
我们在这里,您可以看到覆盖和仅覆盖静态属性之间的差异...查看我用粗体标记的输出行!当我们调用类B的modStaticProperty()时,它也改变了类A中的静态变量的值.由于该静态属性是继承的并且未被覆盖!想一想......
即将推出的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; } }
使用静态作为全局变量(在这种情况下是函数)的经典示例无论语言如何都是一个坏主意.
最强大的方法是创建抽象基类"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"; } }
然后创建一个工厂来"辅助"实例化该功能
class ActionFactory { public static function get($action_name) { //... return AbstractAction instance here } }
然后用它作为:
ActionFactory::get('foo')->do();