正如你在下面看到的,我有一个超类(Article)和两个子类。我希望每个子类都有一个静态数组,它将容纳所有的对象。
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的背景。
3条答案
按热度按时间j9per5c41#
所有内容都只放入一个数组中,原因有二:
$articles
属性仅在Article
类中定义。静态类属性的继承方式与您习惯于非静态属性时所期望的方式不同。虽然它们对子类可用,但它们仍然引用父类上的单个变量-导致您在这里看到的两个子类共享同一个数组的行为。
防止这种情况的唯一方法是在每个子类中定义一个单独的数组,如下所示:
如果将静态变量声明视为在定义类时运行的代码,那么这实际上是有意义的。当定义
Article
类时,会创建一个静态变量并为其分配一个空数组。当定义Interview
和Report
类时,这种情况不会再次发生。只有一次空数组被赋值--只有一个共享变量。add_Object_To_Array()
方法中使用的是self
,而不是static
。self::
引用了它被定义的类,所以由于add_Object_To_Array()
方法是在Article
类中定义的,它将引用Article::$articles
数组。static::
从PHP 5.3开始可用,并引用它被 * 调用 * 的类。这被称为Late Static Binding,并将导致add_Object_To_Array()
引用Report::$articles
或Interview::$articles
,这取决于您调用它的对象的类型。这段代码将引用我们在第一步中声明的两个数组:
2exbekwf2#
我想我会提出一个替代的解决方案,稍微改变您的设计,但不需要在每个子类中的静态定义。根据您的使用情况,这可能是也可能不是比第一个解决方案更好的选择。
这个解决方案使用
get_class()
来查找我们正在存储的对象的类型,然后将其存储在父类中-以classname为键的子数组中:上面的代码没有使用后期静态绑定,所以它可以在任何PHP版本上工作,而不仅仅是PHP 5.3+。
当你用你的原始示例运行这个版本时,你会得到这样的输出:
如果你有PHP 5.3或更高版本,你可以进一步扩展它,并使用
get_called_class()
函数来定义一个getInstances()
静态方法(在Article
类中),其工作方式如下:然后你可以在你的例子中这样调用这个方法:
uqcuzwp83#
对于任何人寻找一个替代的解决方案,除了上述好的。您可以使用PHP的后期静态绑定(
static::
),但也需要在每个子类中单独定义变量(这将使它们独立)。你可以使用这个:
然后,当从每个子类调用
add_Object_To_Array()
时,它将把文章存储在不同的地方。参见Late Static Bindings