How to override trait function and call it from the overridden function?
脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | trait A { function calc($v) { return $v+1; } } class MyClass { use A; function calc($v) { $v++; return A::calc($v); } } print (new MyClass())->calc(2); // should print 4 |
这段代码不起作用,我也找不到一种方法可以像继承一样调用特征函数。我试着打电话给
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | trait A { function calc($v) { return $v+1; } } class MyClass { use A { calc as traitcalc; } function calc($v) { $v++; return traitcalc($v); } } |
没有效果。
有没有办法让它工作,或者我必须完全重写比这个复杂得多的特征函数:)
你上一个就快到了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | trait A { function calc($v) { return $v+1; } } class MyClass { use A { calc as protected traitcalc; } function calc($v) { $v++; return $this->traitcalc($v); } } |
这个特点不是一个阶级。您不能直接访问它的成员。基本上只是自动复制和粘贴…
如果类直接实现方法,它将不使用特性版本。也许你想的是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | trait A { function calc($v) { return $v+1; } } class MyClass { function calc($v) { return $v+2; } } class MyChildClass extends MyClass{ } class MyTraitChildClass extends MyClass{ use A; } print (new MyChildClass())->calc(2); // will print 4 print (new MyTraitChildClass())->calc(2); // will print 3 |
因为子类不直接实现该方法,所以如果不使用父类的特性,它们将首先使用特性的特性。
如果您愿意,特性可以在父类中使用方法(假设您知道该方法会存在),例如。
1 2 3 4 5 6 7 | trait A { function calc($v) { return parent::calc($v*3); } } // .... other code from above print (new MyTraitChildClass())->calc(2); // will print 8 (2*3 + 2) |
您还可以提供重写方法,但仍然可以按如下方式访问特征方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | trait A { function trait_calc($v) { return $v*3; } } class MyClass { function calc($v) { return $v+2; } } class MyTraitChildClass extends MyClass{ use A { A::trait_calc as calc; } } class MySecondTraitChildClass extends MyClass{ use A { A::trait_calc as calc; } public function calc($v) { return $this->trait_calc($v)+.5; } } print (new MyTraitChildClass())->calc(2); // will print 6 echo" "; print (new MySecondTraitChildClass())->calc(2); // will print 6.5 |
您可以在http://sandbox.onlinephpfunctions.com/code/e53f6e8f9834aea5e038aec4766ac7e1c19cc2b5上看到它的工作。
如果感兴趣的话,另一种方法是使用普通OOO方法的额外中间类。这简化了对parent::methodname的使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | trait A { function calc($v) { return $v+1; } } // an intermediate class that just uses the trait class IntClass { use A; } // an extended class from IntClass class MyClass extends IntClass { function calc($v) { $v++; return parent::calc($v); } } |
使用另一个特性:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | trait ATrait { function calc($v) { return $v+1; } } class A { use ATrait; } trait BTrait { function calc($v) { $v++; return parent::calc($v); } } class B extends A { use BTrait; } print (new B())->calc(2); // should print 4 |