There is an abstract MaterialValue class:

 abstract class MaterialValue { public function __construct($model){...} protected static function find($id) { $model = OtherClass::find($id); if($model) return $model return false; } } 

Initially, the task is to ensure that the class, after a successful search, returns its own instance, so the child classes contain the following code:

Product class:

 class Product extends MaterialValue { public static function find($id) { $material = parent::find($id); if($material) return new self($material); return false; } } 

And the class Ingredient :

 class Ingredient extends MaterialValue { public static function find($id) { $material = parent::find($id); if($material) return new self($material); return false; } } 

The code for the find method is identical. The question arises, how to avoid such duplication?

  • one
    in the base class return new static($model); - vp_arth
  • @vp_arth Cool, thanks! Write the answer, please, so that I can mark it. - RostD
  • @RostD Maybe I don’t understand something, but what about OtherClass you have here? - Stanislav Belichenko
  • @RostD And why in the parent class is protected function find($id) , and not protected static function find($id) ? - Stanislav Belichenko
  • one
    @ Stanislav rightly said, so in the end I solved the issue using the "Factory" pattern - RostD

1 answer 1

You can use late static binding:

 abstract class MaterialValue { public function __construct($model){...} protected static function find($id) { $model = OtherClass::find($id); if($model) return new static($model); return false; } } 

In general, the main thing to follow is that the returned type of the method should not change in its heirs.
If you plan to return an instance of MaterialValue in child classes, then the parent method should return it as well.