PHP:子类静态继承-子类共享静态变量?
正如您在下面看到的,我有一个超级类(文章)和两个子类。我希望每个子类都有一个静态数组,该数组将容纳它的所有对象PHP:子类静态继承-子类共享静态变量?,php,inheritance,static,subclass,extend,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_p
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{}
-创建两个报表对象并将其添加到其数组:
$tmp = new Report();
$tmp->add_Object_To_Array();
$tmp = new Report();
$tmp->add_Object_To_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);
-制作两个访谈对象并将其添加到其数组中:
$tmp = new Report();
$tmp->add_Object_To_Array();
$tmp = new Report();
$tmp->add_Object_To_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);
-上面的脚本给出了两个Aray:
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背景。所有东西都只进入一个数组,原因有二:
$articles
属性仅在Article
类中定义
如果您习惯于非静态属性,那么静态类属性不会以您可能期望的方式继承。虽然它们对子类可用,但它们仍然引用父类上的单个变量-导致您在这里看到的两个子类共享同一数组的行为
防止这种情况的唯一方法是在每个子类中定义一个单独的数组,如下所示:
class Report extends Article {
public static $articles = array();
}
class Interview extends Article {
public static $articles = array();
}
public static function getInstances()
{
$class = get_called_class();
// return isset(self::$articles[$class]) ? self::$articles[$class] : array();
if (isset(self::$articles[$class])) {
return self::$articles[$class];
} else {
return array();
}
}
print_r(Report::getInstances());
print_r(Interview::getInstances());
如果您认为静态变量声明是在定义类时运行的代码,那么这实际上是有意义的。定义项目
类时,会创建静态变量并为其分配空数组。当定义了访谈
和报告
类时,这种情况不会再次发生。只有一次空数组被赋值-只有一个共享变量将对象添加到数组()
方法中使用的是self
,而不是static
引用它在中定义的类,因此,由于您的self::
方法是在add_Object_to_Array()
类中定义的,因此它将引用Article
数组Article::$articles
在PHP5.3中开始提供,并引用调用它的类。这称为,并将导致static::
引用将对象添加到数组()
或报告::$articles
,具体取决于调用对象的类型访谈::$articles
public function add_Object_To_Array() {
array_push(static::$articles, $this);
}
我想我会提供一个替代的解决方案,稍微改变一下您的设计,但不需要在每个子类中进行静态定义。根据您的使用情况,这可能比第一个解决方案更好,也可能不是 此解决方案用于查找我们要存储的对象的类型,然后将其存储在父类中-在由classname键入的子数组中:
abstract class Article
{
public static $articles = array();
public function add_Object_To_Array()
{
// get the actual class of the current object
$class = get_class($this);
// define an empty subarray for this class if we haven't seen it before
if (!isset(self::$articles[$class])) {
self::$articles[$class] = array();
}
// add this object to the appropriate subarray
array_push(self::$articles[$class], $this);
}
}
class Report extends Article{}
class Interview extends Article{}
上面的代码不使用后期静态绑定,因此它可以用于任何PHP版本,而不仅仅是PHP5.3+
使用原始示例运行此版本时,将得到如下输出:
class Report extends Article {
public static $articles = array();
}
class Interview extends Article {
public static $articles = array();
}
public static function getInstances()
{
$class = get_called_class();
// return isset(self::$articles[$class]) ? self::$articles[$class] : array();
if (isset(self::$articles[$class])) {
return self::$articles[$class];
} else {
return array();
}
}
print_r(Report::getInstances());
print_r(Interview::getInstances());
数组
(
[报告]=>阵列
(
[0]=>报告对象
(
)
[1] =>报告对象
(
)
)
[采访]=>数组
(
[0]=>采访对象
(
)
[1] =>采访对象
(
)
)
)
如果您使用的是PHP 5.3或更高版本,则可以进一步扩展此功能,并使用此函数定义一个getInstances()
静态方法(在文章
类中),其工作方式如下:
class Report extends Article {
public static $articles = array();
}
class Interview extends Article {
public static $articles = array();
}
public static function getInstances()
{
$class = get_called_class();
// return isset(self::$articles[$class]) ? self::$articles[$class] : array();
if (isset(self::$articles[$class])) {
return self::$articles[$class];
} else {
return array();
}
}
print_r(Report::getInstances());
print_r(Interview::getInstances());
然后您可以在示例中调用此方法,如下所示:
class Report extends Article {
public static $articles = array();
}
class Interview extends Article {
public static $articles = array();
}
public static function getInstances()
{
$class = get_called_class();
// return isset(self::$articles[$class]) ? self::$articles[$class] : array();
if (isset(self::$articles[$class])) {
return self::$articles[$class];
} else {
return array();
}
}
print_r(Report::getInstances());
print_r(Interview::getInstances());
抽象类文章
缺少结尾}$该
在该上下文中指的是抽象类文章
。您将如何将其应用到阵列中?谢谢,但我想:$tmp=new Report()$tmp->add_Object_To_Array()代码>引用了“报表对象的函数”?(面向对象的思考)。我知道抽象类不能有对象。使用static::$articles
而不是self::$articles
谢谢,但我已经尝试过了,它不起作用。@AlexPstatic::
是必需的,但它只是解决方案的一部分。您还需要单独定义变量。非常感谢!很好的回答,包括教育和解决问题!:)美好的我没有完全理解您的扩展方法,更准确地说,返回isset(self::$articles[$class])?self::$articles[$class]:数组()代码>,我不太熟悉这种类型的if语句。如果语句为false
,它是否返回空数组?@MathiasCiarlo我使用的是there。我把它改写成了一个更清晰但本质上相同的版本。