繁体   English   中英

PHP访问父类的属性,而不创建相同属性的“子副本”

[英]PHP accessing a parent class's properties without creating a “child copy” of the same property

我正在做一个将程序代码迁移到类体系结构的项目,但是遇到了我不知道该如何解决的问题。 请参见以下代码:

// StackOverflow example code
# in file classes/parent_class.php
class Parent_class {
  protected $aggregator_array = array();
  const TARGET_DATA_LEVEL = 31; // Bit-mask for selecting appropriate aggregation level

  public function __construct()
  {
    $this->child_class_1 = new child_class_1();
    $this->child_class_2 = new child_class_2();
  }

  protected function aggregate_data($data_level, $message, $file, $function, $line)
  {
    $add2array = $data_level & self::TARGET_DATA_LEVEL;
    if ($add2array > 0)
    {
      // code to create the array's index, based on current time and other factors
      $this->aggregator_array[$index] = $message;
    }
  }
}

# in file classes/child_class_1.php
class child_class_1 extends Parent_class {
  private function do_something()
  {
    // some code here
    $data_level = 1; // simulate an error of some kind
    $message = 'Foo!';
    $this->aggregate_data($data_level, $message, __FILE__, __FUNCTION__, __LINE__);
  }
}

# in file classes/child_class_1.php
class child_class_2 extends Parent_class {
  private function do_something_else()
  {
    // some code here
    $data_level = 2; // simulate nav message
    $message = 'hello world!';
    $this->aggregate_data($data_level, $message, __FILE__, __FUNCTION__, __LINE__);
  }
}

如您所见,我有一个父类,其中包含一个数据聚合方法,还有多个子类,这些子类试图访问相同的方法来存储消息,以便在脚本运行结束时进行检索。 除了没有实现意图(将聚集的消息收集到中央数组中)以外,这一切都很好。 所有对Aggregate_data的调用都运行良好,但是任何子类的调用都会导致将数据存储到该子类自己的Aggregator_array中,这不是最佳选择。 当然,我可以执行array_merge()将子项插入到父数组中,但是如果我有两个以上的子类(并且我希望有六个或更多),我们正在谈论一种编码恶梦。 我已经尝试过使用静态属性,但是显然不起作用,因为我需要动态更改父数组。

所以我的问题是, 如何在不创建同名子属性的情况下从子类更改父对象的属性?

现在,我非常高兴使用“不相关”的类(例如,从当前子类中删除“ extends parent_class”),但是问题就转移到了如何访问不相关类的属性和方法上,我没有如果可能的话,如何做的最模糊的线索。

child_class_ *对象真的是不同种类的Parent_class吗? 还是为了聚集某些东西而只是为了与Parent_class交互? 基于方法名称do_something和do_something_else,它们实际上并不负责这种逻辑。 除非您要重写/定义特定类型的Parent_class的特定行为,例如,如果您希望aggregate_data()的行为进行多态更改,则可能不需要扩展Parent_class。

就是说,访问“无关”类属性的一种方法是将Parent_class的实例传递到do_ *函数中:

// in your main script
$aggregator = new Parent_class();
$thing1->do_something( $aggregator );
$thing2->do_something_else( $aggregator );

// in child_class_1, which you should rename ;-)
private function do_something( $aggregator )
{
    ...
    $aggregator->aggregate_data( $data_level, $message, __FILE__, __FUNCTION__, __LINE__ );
}

// in child_class_2, ditto
private function do_something_else( $aggregator )
{
    ...
    $aggregator->aggregate_data( $data_level, $message, __FILE__, __FUNCTION__, __LINE__ );
}

另外,您可以将Parent_class的实例传递到两个“子”类的构造函数中。 这样可以使do_ *方法的方法签名更加混乱。 然后,您可以执行以下操作:

// main script
$aggregator = new Parent_class();
$thing1 = new child_class_1( $aggregator );
$thing2 = new child_class_2( $aggregator );

// within each of the do_* methods:
$this->$aggregator->aggregate_data( $data_level, $message, __FILE__, __FUNCTION__, __LINE__ );

对于这种方法,请确保还添加了一个构造函数,该构造函数在“子”类中设置了$ this-> aggregator。

在代码的后面,您可以通过调用$aggregator->GetAggregatorArray或其他方法来访问“中央数组”。

另外,您不会初始化$index ,但是无论如何您都不需要该变量(假设$aggregator_array是一个数字数组)。 您可以这样做:

$this->aggregator_array[] = $message;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM