W3docs

final

A palavra-chave "final" em PHP permite marcar uma classe, método ou constante como final, impedindo que subclasses os modifiquem ou redeclarem.

A Palavra-chave final do PHP

final é uma palavra-chave de orientação a objetos em PHP que bloqueia parte de uma classe para que subclasses não possam alterá-la. Você pode aplicá-la a uma classe (nenhuma outra classe pode estendê-la), a um método (nenhuma subclasse pode substituí-lo) ou, desde o PHP 8.1, a uma constante (nenhuma subclasse pode redefini-la).

Marcar algo como final é uma declaração deliberada de design: "este comportamento é intencional e as classes filhas não devem alterá-lo." Bem utilizado, previne substituições acidentais, documenta a intenção no código e permite raciocinar sobre uma classe sem se preocupar que uma subclasse tenha silenciosamente alterado seu funcionamento. Esta página aborda cada forma de final, quando usá-lo e as armadilhas que costumam pegar as pessoas de surpresa.

Já familiarizado com subclasses e substituições? final só faz sentido no contexto de herança em PHP e classes e objetos.

Classes finais

Uma classe final não pode ser estendida. Qualquer tentativa de declarar uma subclasse produz um erro fatal em tempo de compilação:

<?php

final class PaymentGateway
{
    public function charge(float $amount): string
    {
        return "Charged $amount";
    }
}

// Fatal error: Class CryptoGateway cannot extend final class PaymentGateway
class CryptoGateway extends PaymentGateway {}

Use uma classe final quando seu comportamento é completo e a herança seria um uso indevido — por exemplo, um objeto de valor, um serviço cujo contrato você controla, ou uma classe sensível à segurança onde uma subclasse que sobrescreve poderia contornar uma verificação.

Métodos finais

Você pode manter uma classe extensível, mas bloquear métodos individuais. Um método final pode ser herdado e chamado por subclasses, mas não pode ser substituído:

<?php

class Account
{
    protected float $balance = 0;

    // Subclasses may add behavior, but must not change how withdrawing works.
    final public function withdraw(float $amount): void
    {
        if ($amount > $this->balance) {
            throw new RuntimeException("Insufficient funds");
        }
        $this->balance -= $amount;
    }
}

class SavingsAccount extends Account
{
    public function addInterest(float $rate): void
    {
        $this->balance += $this->balance * $rate;
    }

    // Fatal error: Cannot override final method Account::withdraw()
    // public function withdraw(float $amount): void {}
}

Este é o uso mais comum de final: você deseja que uma classe seja aberta para extensão em geral, mas um método específico impõe um invariante (aqui, nunca se pode sacar mais do que o saldo) que nenhuma subclasse deve poder enfraquecer.

"Experimente Você Mesmo" não está disponível para este exemplo.

Um método private já é efetivamente final — não é visível para subclasses, portanto marcar um método privado como final é redundante (e o PHP 8 emite um aviso para final private, exceto no construtor).

Constantes finais (PHP 8.1+)

Antes do PHP 8.1, uma subclasse podia redefinir uma constante herdada. O PHP 8.1 adicionou final para constantes, permitindo que você evite isso:

<?php

class HttpStatus
{
    final public const OK = 200;
}

class ApiStatus extends HttpStatus
{
    // Fatal error: ApiStatus::OK cannot override final constant HttpStatus::OK
    // public const OK = 201;
}

Se você precisa de constantes que fazem parte de um contrato fixo — códigos de status, nomes de papel, chaves de configuração — final garante que toda subclasse as respeite. Saiba mais em constantes de classe.

Propriedades finais (PHP 8.4+)

Antes do PHP 8.4, final não podia ser aplicado a uma propriedade. O PHP 8.4 adicionou propriedades final: uma propriedade final ainda pode ser lida e escrita, mas uma subclasse não pode redeclará-la.

<?php

class Car
{
    final public string $model = "Toyota";
}

class Toyota extends Car
{
    // Fatal error: Cannot override final property Car::$model
    // public string $model = "Corolla";
}

Observe que final controla a redeclaração, não a mutabilidade — o valor ainda pode ser reatribuído em tempo de execução. Para tornar um valor imutável após a construção, use uma propriedade readonly; os dois modificadores são frequentemente combinados (final public readonly string $model). No PHP 8.3 e anteriores, marcar qualquer propriedade como final é um erro fatal.

final vs. abstract

final e abstract são opostos e não podem ser combinados:

  • abstract significa deve ser implementado por uma subclasse — requer herança.
  • final significa não pode ser estendido ou substituído — proíbe herança.

Declarar final abstract class é um erro fatal. Veja classes abstratas para o outro lado desta moeda.

Quando usar final

  • Bloquear um invariante. Um método final garante que a lógica crítica (validação, verificações de segurança, faturamento) não possa ser silenciosamente alterada mais adiante.
  • Sinalizar classes "concluídas". Uma classe final informa aos leitores que o design é intencional e não se destina a ser subclassificado.
  • Preferir composição em vez de herança. Quando você prefere que os consumidores envolvam sua classe em vez de estendê-la, final os orienta nessa direção.

Um contra-argumento comum: final pode dificultar o teste ou a simulação do código, já que você não pode criar uma subclasse de uma classe final. A resposta moderna é depender de interfaces (de modo que você simule a interface, não a classe concreta) — veja interfaces. Recorra a final quando a restrição for genuinamente parte do design, não como um hábito indiscriminado.

Conclusão

A palavra-chave final fecha uma classe, método ou constante para modificação por subclasses, transformando uma intenção de design em uma regra imposta pelo compilador. Use-a em classes que estão completas, em métodos que protegem invariantes e em constantes que formam um contrato fixo — mas lembre-se de que não pode ser aplicada a propriedades e não pode ser combinada com abstract.

Prática

Prática
O que a palavra-chave 'final' indica em PHP?
O que a palavra-chave 'final' indica em PHP?
Was this page helpful?