【问题标题】:method overriding for single instance v2单实例 v2 的方法覆盖
【发布时间】:2020-10-10 22:12:08
【问题描述】:

是否可以覆盖单个实例的方法?例如

class test
{
    protected function print()
    {
    echo "printed from old method";
    }
}

$a= new test();
can i overrride method "print" only for object $a?
e.g. $a->test=function(){echo "printed with new method";}

我知道这有点奇怪,但在我的项目中,一个公共类(“base”)是许多其他类的一部分,每个类都需要稍微修改版本的“base”。我只需要每次覆盖一种方法。尽量避免为此创建大量的“base”子类。

附言我已经看到你提议的solution,但它对我不起作用。 php版本为7.4.3

这是我的代码:

class nodeGroup
{
    public function test()
    {
        echo "internal";
    }
        
}

$a= new nodeGroup();
$a->test = (function() {
    echo "external";
})->bindTo($a);

$a->test();

result is "internal"

【问题讨论】:

  • 这不违反 OCP 吗?
  • 你考虑过使用接口吗?
  • 我认为正确的做法是要么创建一个从原始类继承并覆盖方法的新类,要么使用接口。另一种选择是添加一个成员,该成员是指向要调用的函数的指针,如果它不为假,则在方法中调用它,否则,使用普通方法函数。我认为这违反了最小意外的政策,并且尝试覆盖实例对象上的方法肯定会这样做。

标签: php oop overriding


【解决方案1】:

您可以即时声明anonymous class

$a = new class extends nodeGroup {
    public function test()
    {
        echo 'external';
    }
};

$a->test();  // 'external'

Demo

【讨论】:

  • 这可能是解决方案,但实际类有许多其他方法和属性不会改变,需要在匿名类中再次声明。
  • @ParakmiI 不,他们不会:这个匿名类扩展了nodeGroup,因此它继承了它的所有内容(除了您明确覆盖的内容)。使用相应的示例编辑了演示链接。
  • 我不知道你能做到这一点。似乎是一个非常好的解决方案。谢谢。
  • @ParakmiI 它从 PHP 7 开始可用。不是最常见的功能,但它有它的用途。
【解决方案2】:

你可以给类添加一个属性,print()方法可以检查该属性是否被设置。

class test
{
    public $print_function;

    public function print()
    {
        if (isset($this->$print_function)) {
            ($this->$print_function)();
        } else {
            echo "printed from old method";
        }
    }
}

$a = new test();
$a->print_function = function() {
    echo "printed with new method";
};
$a->print();

【讨论】:

  • 这很好用谢谢。但是,了解是否有更简洁的方法来替代实例中的方法会很有用。怕是没有……
  • “干净”的方法是定义一个子类并使用它。
猜你喜欢
  • 2012-07-19
  • 1970-01-01
  • 1970-01-01
  • 2023-02-09
  • 2011-01-04
  • 2010-09-28
  • 2012-05-09
相关资源
最近更新 更多