[go: up one dir, main page]

Em orientação a objetos, uma metaclasse é uma classe cujas instâncias também são classes e não objetos no sentido tradicional. Assim como classes definem o comportamento de certos objetos, metaclasses definem o comportamento de certas classes e suas instâncias.

Nem toda linguagem orientada a objeto suporta metaclasses. Entre as que suportam, a extensão de modificações que podem ser feitas nas classes varia. Cada linguagem possui seu próprio protocolo de metaobjeto, um conjunto de regras que definem como objetos, classes e metaclasses interagem.

Exemplo em Python

editar

Em Python, a classe nativa type é uma metaclasse. Considere o exemplo abaixo:

class Carro(object):
    __slots__ = ['marca', 'modelo', 'ano', 'cor']

    def __init__(self, marca, modelo, ano, cor):
        self.marca = marca
        self.modelo = modelo
        self.ano = ano
        self.cor = cor

    @property 
    def descricao(self):
        """ Retorna uma descrição do carro. """
        return "%s %s %s %s" % (self.cor, self.ano, self.marca, self.modelo)

Em tempo de execução, Carro é um objeto type por herança. O código fonte da classe Carro mostrado acima não inclui detalhes como o tamanho em bytes dos objetos Carro, sua configuração na memória, como são alocados, que o método __init__ é invocado automaticamente cada vez que um objeto é criado, e assim por diante. Esses detalhes aparecem não somente quando um novo objeto Carro é criado, mas também cada vez que um atributo na classe é acessado. Em linguagens de programação sem metaclasses, esses detalhes são definidos pela especificação da linguagem e não podem ser modificados. Em Python, a metaclasse nativa type controla tais detalhes sobre o comportamento de Carro. Tais detalhes pode ser modificados usando-se outra metaclasse ao invés de type.

O exemplo acima contém código redundante relacionado aos quatro atributos marca, modelo, ano e cor. É possível eliminar parte da redundância usando uma metaclasse. Em Python, uma metaclasse é definida como uma subclasse de type.

 class TipoIniciaAtributo(type):
     def __call__(self, *args, **kwargs):
         """ Cria uma nova instância. """
 
         # Primeiro, cria um objeto da forma padrão.
         obj = type.__call__(self, *args)
 
         # Adicionalmente, configura-se atributos do novo objeto.
         for nome in kwargs:
             setattr(obj, nome, kwargs[nome])
 
         # Retorna o novo objeto.
         return obj

Essa metaclasse modifica a criação do objeto. Todos os outros aspectos do comportamento da classe e dos objetos ainda seguem o que foi definido por type.

Agora a classe Carro pode ser reescrita para usar essa metaclasse acima, o que é feito atribuindo a nova metaclasse em __metaclass__:

 class Carro(object):
     __metaclass__ = TipoIniciaAtributo
     __slots__ = ['marca', 'modelo', 'ano', 'cor']
 
     @property
     def descricao(self):
         """ Retorna uma descrição do carro. """
         return "%s %s %s %s" % (self.cor, self.ano, self.marca, self.modelo)

Objetos Carro podem então ser instanciados através de:

 carros = [
     Carro(marca='Toyota', modelo='Prius', ano=2005, cor='green'),
     Carro(marca='Ford', modelo='Prefect', ano=1979, cor='blue')]

Suporte em linguagens

editar

As seguintes linguagens de programação suportam metaclasses:

Ver também

editar