php - PHP中静态成员的继承

标签 php inheritance

在 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/

相关文章:

php - CakePHP 查找最近的日期

php - MySQL内连接输出到php中的html表

c++ - 继承的构造函数和 STL 容器错误

c++ - "Holder"存储不同对象类型的模板类。带参数和不带参数的构造函数

c++ - 从父类(super class)函数返回子类定义

php - 根据用户偏好对表格内的项目进行排序,正确的方法是什么?

php - 比较时间戳

php - Laravel - Larabook 教程 :Users. Codeception 确实看到了新记录

Python 修饰类中的方法和继承

c++ - 使用共享指针访问单例子类时出现 SEGFAULT