Professor, Pra fixar, fiz um código mostrando a importância de usar a key word final. Neste exemplo, mostro como burlar uma validação, estendendo a classe CPF e passando pela validação.
Para evitar que isso ocorra, basta usar o key word final na classe CPF ou no método valida.
É isso mesmo ?
<?php
// Enter your code here, enjoy!
class CPF
{
    private $numero;
    public function __construct($num)
    {
        if($this->valida($num)){
            $this->numero = $num;    
        }else{
            echo 'CPF invalido';
            exit();
        }
    }
    protected function valida($num)
    {
        // digamos que validacao seja apenas ter 11 letras
        if(strlen($num) != 11) {
            return false;
        }
        return true;
    }
    public function __toString()
    {
        return $this->numero;
    }
}
class Pessoa
{
    private $name;
    private $cpf;
    public function __construct($name, CPF $cpf)
    {
        $this->name = $name;
        $this->cpf = $cpf;
    }
    public function getDados()
    {
        return "Nome: {$this->name}, CPF: {$this->cpf}" . PHP_EOL;
    }
}
// Classe estendida propositalmente para burlar validacao do CPF
// Isso mostra a importancia de usar a key-word final na classe ou no método de validação
class CPFinvalido extends CPF
{
    protected function valida($num)
    {
        return true;
    }
}
// output: Nome: John Doe, CPF: 12345678910
$umaPessoaCPFValido = new Pessoa(
    'John Doe',
    new CPF('12345678910')
);
echo $umaPessoaCPFValido->getDados();
// output: Nome: Mary Doe, CPF: aaa, deveria ser: CPF inválido
$umaPessoaCPFInvalido = new Pessoa(
    'Mary Doe',
    new CPFinvalido('aaa') // Passando um CPF invalido que burla validacao
);
echo $umaPessoaCPFInvalido->getDados();
 
            