Sobrecarga de método em php

Sobrecarga é um conceito de polimorfismo, um dos fundamentos da orientação à objetos, ou seja, sobrecarga significa que um elemento pode se comportar como outros e desempenhar várias funções.

Sobrecarga é um polimorfismo Ad-hoc, onde vários métodos possuem o mesmo nome mas a sua assinatura é diferente. Para saber mais sobre o conceito de polimorfismo consulte o link: http://pt.wikipedia.org/wiki/Polimorfismo.

Este é um conceito bastante útil e interessante, sua utilização, porém, gera sempre polêmica e deve ser usado com muito cuidado, pois o uso exagerado pode deixar o seu código complicado de se entender.

A implementação dessa especificação (sobrecarga) da orientação à objetos não é realizado em todas as linguagens e como é de se esperar o PHP também não a implementa, muito por causa de sua natureza bastante dinâmica combinado com sua tipagem fraca.

Mas então, se esta especificação não é implementada no PHP como poderemos utilizar?

Gostaria de lembrar que isto não é nenhuma novidade e já foi largamente abordado em outros blogs e fontes de dados pela internet a fora então, não se decepcionem.

Bom, o PHP nos dá três métodos que “auxiliam” a criação de uma sobrecarga. Ela não é natural, mas ainda assim pode ser realizada. Os métodos são: func_get_arg, func_get_args, func_num_args.

func_get_arg

Esta função permite que você recupere o valor de um argumento passado como parâmetro na chamada do método.

public function sobrecarga() {
    return $argumento = func_get_arg(0);
}

func_get_args

Esta função retorna um vetor com todos os argumentos passados como parâmetro na chamada do método.

public function sobrecarga() {
    var_dump(func_get_args());
}

func_num_args

Esta função retorna um inteiro que representa a quantidade de argumentos passados como parâmetro ao seu método.

public function sobrecarga() {
    return $quantidade = func_num_args();
}

Bom, e agora? Vamos à sobrecarga

Agora que já foram mostrados as funções que serão utilizadas vou mostrar, por código, como se implementa a sobrecarga no PHP.

A sobrecarga que irei mostrar será de dois tipo: sobrecarga por quantidade de parâmetros e sobrecarga por tipo de parâmetros.

Sobrecarga por quantidade

Para implementar este tipo de sobrecarga, basta escrever um método (sem argumentos) e na implementação deste método o método func_num_args será chamado para verificarmos com quantos parâmetros estamos trabalhando.

class Sobrecarga {
    public function sobrecargaUm() {
        if (func_num_args() == 2) {
            $this->_metodoChamadoComDoisArgumenos(
                func_get_arg(0), func_get_arg(1)
            );
        } else if (func_num_args() == 3) {
            $this->_metodoChamadoComTresArgumentos(
                func_get_arg(0), func_get_arg(1), func_get_arg(2)
            );
        } else {
            throw new Exception("Número de argumentos inválido");
        }
    }
}
$sobrecarga = new Sobrecarga();
$sobrecarga->sobrecargaUm("Hello","World");
$sobrecarga->sobrecargaUm("Hello","World", "Again");

Sobrecarga por tipo

Para implementar este tipo de sobrecarga basta recuperar os argumentos passados por parâmetros e testar o tipo de cada um deles.

class Sobrecarga {
    public function sobrecargaDois() {
        if (func_num_args() == 1) {
            if (is_numeric(func_get_arg(0)) {
                $this->_metodoSeArgumentoNumerico(func_get_arg(0));
            } else {
                $this->_metodoSeArgumentoString(func_get_arg(0));
            }
        } else {
            throw new Exception("Número de argumentos inválido");
        }
    }
}
$sobrecarga = new Sobrecarga();
$sobrecarga->sobrecargaDois("Hello");
$sobrecarga->sobrecargaDois(21);

Devemos usar?

Bom, como vocês podem notar, isto não é uma implementação natural. Foram utilizados meios para fazer com que a sobrecarga seja válida, a opção para o uso é de quem programa e com certeza a linguagem deve ser aproveitada em todo seu potencial.

Mas ao mesmo tempo, como é bastante perceptível, a implementação de uma sobrecarga deixa o código “feio” e difícil de ser compreendido, além de existir a necessidade de fazer vários testes para a chamada de um simples método. Isto faz com que sua aplicação fique mais propensa à erros.

A recomendação em geral é para que cada método possua sua própria assinatura única, este tipo de sobrecarga deve ser usado somente em casos extremamente necessários (isso varia com o bom senso do programador).

Mas fica uma dica importante, em caso de utilização de sobrecarga (ou mesmo sem utilizá-la) comente seu código com docblocks. Já que a assinatura do método não é completa (os argumentos não são descritos), facilita, com a leitura do comentário, descobrir o comportamento do método.