【问题标题】:How to update a parent constructor variable in BOTH child classes when one child class updates value of constructor variable?当一个子类更新构造函数变量的值时,如何更新两个子类中的父构造函数变量?
【发布时间】:2017-05-12 14:36:49
【问题描述】:

首先,我相信我的问题与 this question 不同。

我已经为我正在开发的应用程序编写了自己的框架但我一直遇到 1 个特定的(IMO,次要)架构问题,我认为应该有更好的解决方案

假设两个类继承自一个父类:

class AAA {
    public function __construct() {
        $this->go_between = __CLASS__;
    }
    // many other methods in here which BBB and CCC require
}

class BBB extends AAA {
    public function __construct() {
        parent::__construct();
    }

    public function mutatorBBB() {
        $this->go_between = __CLASS__;
    }
}

class CCC extends AAA {
    public function __construct() {
        parent::__construct();
    }

    public function returnValue() {
        return $this->go_between;
    }
}

现在假设您在BBBCCC 中都需要一个“go_between”变量,因为在BBB 的某处,您必须使用CCC 中的方法,即,

$CCC = new CCC(); // somewhere in class BBB so the methods of CCC can be used

因此,如果您在索引中运行以下代码:

$BBB = new BBB();
$CCC = new CCC();

echo $BBB->go_between;
echo "\n";
echo $CCC->go_between;

生成以下预期输出:

AAA
AAA

但是,假设您更新了其中一个子类中的“中间人”构造函数变量的值:

$BBB->mutatorBBB();
echo $BBB->go_between;
echo "\n";
echo $CCC->returnValue();

在这种情况下,会生成以下输出:

BBB // mutatorBBB() updated the value of $this->go_between
AAA // Why doesn't class CCC "see" the updated value of the go-between variable? That is, why doesn't CCC "see" the value as updated by mutatorBBB()? (that is ----> 'BBB')

我能够轻松克服这个问题,但我不认为这是“最佳实践”:

class Common {
    static $go_between; // initialize
}

现在稍微重构类:

class AAA {
    public function __construct() {
        Common::$go_between = __CLASS__;
    }
    // many other methods in here which BBB and CCC require
}

class BBB extends AAA {
    public function __construct() {
        parent::__construct();
    }

    public function mutatorBBB() {
        Common::$go_between = __CLASS__;
    }
}

class CCC extends AAA {
    public function __construct() {
        parent::__construct();
    }

    public function returnValue() {
        return Common::$go_between;
    }
}

现在输出如下:

$BBB->mutatorBBB();
echo Common::$go_between;
echo "\n";
echo $CCC->returnValue();

这是(即我的申请所需的结果):

BBB
BBB

我曾多次不得不退回到全局命名空间中的 static 类来完成此操作。

是否有一种更“面向对象”的方法来更新父构造函数中的中间变量,这些变量由 2 个子类使用,其中一个子实例化并需要第二个子类?

【问题讨论】:

  • $BBB$CCC 在实例化时从父级继承值;在那之后,它们是完全独立的对象——改变一个对象的属性不会影响另一个对象,即使该属性是从父对象继承的。在大多数情况下,这就是您想要的; DogCat 可能都从 Mammal 继承 numberOfLegs 属性,但是,倒霉的休伯特腊肠犬(Dog 对象)在交通拥挤时失去了一条腿......

标签: php oop constructor


【解决方案1】:

如果您想在两个实例之间创建一个通信通道,该通道应该是一个单独的对象。

你应该更喜欢组合而不是继承。

有点像这样:

$channel = new Channel;
$foo = new Foo($channel);
$bar = new Bar($channel);

$foo->writeToChannel('aaa');
echo $bar->readFromChannel();

此处的示例:https://3v4l.org/burHd

【讨论】:

  • 不错的解决方案 - 我会说我的“hack”解决方案更快(实施),但你会认为它是“坏”的做法吗?我想更干净地编码,但不确定我的解决方案的缺点
  • 好的,谢谢 - 有道理。另外,我不得不担心过度填充全局命名空间,这使得我的变量名越来越冗长和“有创意”
  • @TheOneandOnlyChemistryBlob 您应该始终专注于使代码更易于理解。与编写新代码相比,您花在阅读和编辑旧代码上的时间要多得多。
猜你喜欢
  • 2014-12-16
  • 2018-06-06
  • 2016-08-18
  • 1970-01-01
  • 2019-05-25
  • 2021-12-25
  • 2013-09-11
  • 1970-01-01
  • 2020-01-16
相关资源
最近更新 更多