PHP:子类静态继承 - 子共享静态变量?

Mat*_*rlo 6 php inheritance static subclass extend

正如你在下面看到的,我有一个超类(文章)和两个子类.我希望每个子类都有一个静态数组,它可以保存所有它的对象.

abstract class Article
{
    public static $articles = array(); // Variable for storing all the objects of each sub-class.

    public function add_Object_To_Array()
    {       
        array_push(self::$articles, $this);
    }
}

class Report extends Article{}
class Interview extends Article{}
Run Code Online (Sandbox Code Playgroud)

- 制作两个Report对象并将它们添加到数组中:

$tmp = new Report();
$tmp->add_Object_To_Array();

$tmp = new Report();
$tmp->add_Object_To_Array();
Run Code Online (Sandbox Code Playgroud)

- 制作两个Interview对象并将它们添加到数组中:

$tmp = new Interview();
$tmp->add_Object_To_Array();

$tmp = new Interview();
$tmp->add_Object_To_Array();

print_r(Report::$articles);
print_r(Interview::$articles);
Run Code Online (Sandbox Code Playgroud)

- 上面的脚本吐出了两个arays:

Array
(
    [0] => Report Object()

    [1] => Report Object()

    [2] => Interview Object()

    [3] => Interview Object()   
)
Array
(
    [0] => Report Object()

    [1] => Report Object()

    [2] => Interview Object()

    [3] => Interview Object()    
)
Run Code Online (Sandbox Code Playgroud)

如果你问我,它看起来非常相似,但第一个应该只包含Reports,第二个只包含Interviews.

1.似乎只有一个数组,为什么它只有一个数组?
2.我在同一个类中有一个静态容器对象,这是不好的编码?(有什么建议?)

我对php很新,但有java的背景知识.

jcs*_*nyi 13

由于两个原因,一切都只进入一个阵列:

  1. $articles属性仅在Article类中定义.

    如果您习惯使用非静态属性,则静态类属性不会以您期望的方式继承.虽然他们提供给子类,他们仍然引用父类中的单个变量-导致你在这里看到的其中两个子类都共享同一个阵列的行为.

    防止这种情况的唯一方法是在每个子类中定义一个单独的数组,如下所示:

    class Report extends Article {
        public static $articles = array();
    }
    class Interview extends Article {
        public static $articles = array();
    }
    
    Run Code Online (Sandbox Code Playgroud)

    如果您将静态变量声明视为在定义类时运行的代码,这实际上是有意义的.在Article定义类时,会创建一个静态变量并为其分配一个空数组.定义InterviewReport类时不会再发生这种情况.只有一次空数组被分配 - 只有一个共享变量.

  2. 你用的selfadd_Object_To_Array()方法而不是static.

    • self::指的是它定义的类,所以既然你的add_Object_To_Array()方法是在Article类中定义的,那么它将引用Article::$articles数组.

    • static::从PHP 5.3开始可用,并引用它所调用的类.这称为Late Static Binding,它将导致add_Object_To_Array()引用Report::$articles或者Interview::$articles根据您调用它的对象的类型.

    此代码将引用我们在第一步中声明的两个数组:

    public function add_Object_To_Array() {
        array_push(static::$articles, $this);
    }
    
    Run Code Online (Sandbox Code Playgroud)