看看此示例,并注意指示的输出。

<?php

class Mommy
{
    protected static $_data = "Mommy Data";

    public static function init( $data )
    {
        static::$_data = $data;
    }

    public static function showData()
    {
        echo static::$_data . "<br>";
    }
}

class Brother extends Mommy
{
}

class Sister extends Mommy
{
}

Brother::init( "Brother Data" );
Sister::init( "Sister Data" );

Brother::showData(); // Outputs: Sister Data
Sister::showData(); // Outputs: Sister Data

?>

我的理解是使用 静止的 关键字将指儿童课,但显然,每当子类中缺少该课程时,它都会神奇地适用于父班。 (对于PHP来说,这是一种危险的行为,详细介绍了下面的说明。)

我有以下两件事,说明为什么要这样做:

  1. 我不希望在所有儿童课程中定义所有属性的冗余。
  2. 我希望将属性定义为父类中的默认值,我希望子类定义能够在需要的任何地方覆盖这些属性。每当有默认值时,子类都需要排除属性,这就是为什么我不在上面示例中定义子类中的属性的原因。

但是,如果我们想在运行时覆盖属性(通过INIT方法),它将为父类覆盖它!从那时起,前面初始初始化的儿童课(如兄弟而言)出乎意料地改变了您。

显然,这是由于儿童课程没有自己的静态属性的副本,每当没有明确定义子级的静态属性的结果 - 但是而不是抛出错误,而是要切换的行为 静止的 访问父。所以, 是否有某种方式可以动态地创建属于子类的属性而不会出现在子类定义中的情况下? 这样,子类可以拥有自己的静态属性副本,并且静态关键字可以正确地指它,并且可以书写以考虑到父属性默认值。

还是还有其他解决方案,好,坏或丑陋?

有帮助吗?

解决方案

它确实是指正确的类,只是,除非重新定义或以其他方式破坏了参考集,否则子类中的静态属性与超级类中的参考集中。

因此,您必须这样做:

class Brother extends Mommy
{
    protected static $_data;
}

或者:

class Brother extends Mommy
{
}

$tmp = null;
Brother::$_data =& $tmp;
unset($tmp);
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top