PHP:子类静态继承-子代共享静态变量? [英] PHP: Sub class static inheritance - children share static variables?

查看:356
本文介绍了PHP:子类静态继承-子代共享静态变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

正如您在下面看到的,我有一个超类(文章)和两个子类.我希望每个子类都有一个静态数组,该数组应包含所有对象.

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{}

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

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

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

-制作两个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);

-上面的脚本显示了两个愿望:

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()    
)

如果您问我,这看上去很相似,但第一个只包含报告,第二个只包含访谈.

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

我是php的新手,但是有Java的背景.

解决方案

由于两种原因,一切都只进入一个数组:

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

    如果您习惯了非静态属性,则静态类属性不会像您期望的那样继承.虽然它们对子类可用 ,但它们仍在父类上引用单个变量-导致您在此处看到的行为,即两个子类共享同一数组.

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

    class Report extends Article {
        public static $articles = array();
    }
    class Interview extends Article {
        public static $articles = array();
    }
    

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

  2. 您在add_Object_To_Array()方法中使用的是self,而不是static.

    • self::引用它定义的类,因此,由于您的add_Object_To_Array()方法是在Article类中定义的,因此它将引用Article::$articles数组.

    • static::从PHP 5.3开始可用,并引用被称为 的类.这称为后期静态绑定,并且

    • 会导致add_Object_To_Array()引用Report::$articlesInterview::$articles,具体取决于调用对象的类型.

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

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

As you can see below I have a super class (Article) and two sub classes. I want each of the sub classes to have a static array that shall hold all it's objects.

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{}

-Making two Report objects and adding them to their array:

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

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

-Making two Interview objects and adding them to their array:

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

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

print_r(Report::$articles);
print_r(Interview::$articles);

-The above script spits out the two 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()    
)

Which looks pretty similar if you ask me, but the first one should only contain Reports, and the second one only Interviews.

1. It seems that there is only one array, why is it only one array?
2. I have a static container of objects in the same class, is this bad coding? (Any suggestions?)

I'm pretty new to php, but have a background from java.

解决方案

Everything is going into only one array for two reasons:

  1. The $articles property is only defined in the Article class.

    Static class properties do not get inherited the same way you might expect if you're used to non-static properties. While they are available to the child classes, they're still referencing a single variable on the parent class - resulting in the behavior you're seeing here where both child classes are sharing the same array.

    The only way to prevent this is to define a separate array in each of your child classes, like this:

    class Report extends Article {
        public static $articles = array();
    }
    class Interview extends Article {
        public static $articles = array();
    }
    

    This actually makes sense if you think of the static variable declarations as code that gets run when the class is defined. Creating a static variable and assigning an empty array to it happens when the Article class is defined. It doesn't happen again when the Interview and Report classes are defined. There's only one time that an empty array is getting assigned - there's only one shared variable.

  2. You're using self in your add_Object_To_Array() method instead of static.

    • self:: refers to the class it is defined in, so since your add_Object_To_Array() method is defined in the Article class, it'll refer to the Article::$articles array.

    • static:: Is available starting in PHP 5.3, and refers to the class it is called on. This is known as Late Static Binding, and will result in add_Object_To_Array() referring to either Report::$articles or Interview::$articles depending on the type of the object you're calling it on.

    This code will reference the two arrays that we declared in the first step:

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

这篇关于PHP:子类静态继承-子代共享静态变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆