Adding a trait is an efficient way to extend a "final" class, overriding methods and adding new ones, without having to individually add each method as a closure. It also results in more readable code.
<?php
declare(strict_types=1);
final class ParentC
{
    public $parentvar;
    public $secondvar;
    
    function __construct() { echo( "\r\n<br/>".$this->parentvar = 'set by '.get_class().'->parentconstruct' ); }
    function parentf() { echo( "\r\n<br/>".get_class().'->parentf >> '.$this->parentvar ); }
}
trait ChildC {
    function __construct() {
        parent::__construct();
        echo( "\r\n<br/>".get_class().'->overridden_constructor >> '.$this->parentvar );
    }
    
    function parentf() {
        parent::parentf();
        echo( "\r\n<br/>".get_class().'->overridden_parentf >> '.$this->parentvar );
    }
    
    function dynamicf( $parm = null ) {
        $this->secondvar = empty( $parm ) ? 'set by '.get_class().'->dynamicf' : $parm;
        echo( "\r\n<br/>".get_class().'->dynamicf >> '.$this->parentvar );
    }
}
$definition = new \Componere\Definition( 'ChildC', ParentC::class );
$definition->addTrait( 'ChildC' );
$definition ->register();
$dyno = new ChildC;
$dyno->parentf();
$dyno->dynamicf( 'myvalue ');
var_dump( $dyno instanceof ChildC, $dyno instanceof ParentC, is_a( $dyno, 'ParentC') );
var_dump( $dyno );
?>
will output:
set by ParentC->parentconstruct 
ChildC->overridden_constructor >> set by ParentC->parentconstruct 
ParentC->parentf >> set by ParentC->parentconstruct 
ChildC->overridden_parentf >> set by ParentC->parentconstruct 
ChildC->dynamicf >> set by ParentC->parentconstruct
boolean true
boolean true
boolean true
object(ChildC)[2]
  public 'parentvar' => string 'set by ParentC->parentconstruct' (length=31)
  public 'secondvar' => string 'myvalue ' (length=8)