ruby和python都有monkey patch,也就是可以在运行时修改某个对象或类的方法
在过去php是没有这种特性的,如果要给一个对象添加方法只有继承
<?php
class A
{
public function foo()
{
return 'foo';
}
}
$obj = new A();
如果在某个情况下,我们要给$obj
对象添加一个方法,这时候该怎么办呢?
<?php
class B extends A
{
public function bar()
{
return 'bar';
}
}
$obj = new B();
这样obj对象就有了bar
方法,但是这种办法很傻,得新建一个子类,而且这个子类可能很难被用上,如果在另外的情况下要用到另一个新的方法bar2
,这时候又该怎么办呢,是再写一个继承?继承A还是B呢?
php7提供了一个新的语法叫做匿名类 在上面的例子中,要给类A的实例添加方法就不需要新建一个类文件然后去继承,直接
<?php
$obj = new class extends A
{
public function bar()
{
return 'bar';
}
};
这样obj也有bar
方法,但是却没有创建额外的类文件,毕竟目的只是作为临时补丁修复一下,如果能够确定这个方法会被很多地方用到,那么就得考虑是否把这个方法添加到基类中,还是放到单独的子类。
在测试中这特性非常有用,测试protected
方法,构造mock
对象而不用改原有代码,第一次在真实场景中见到是在activity-log这个项目中https://github.com/spatie/laravel-activitylog/blob/master/tests/DetectsChangesTest.php这里就构造了仅仅用于测试的model对象而没有改写原有的model