Métaclasse
Source: Wikipédia sous licence CC-BY-SA 3.0.
La liste des auteurs de cet article est disponible ici.

Une métaclasse est une classe dont les instances sont des classes. Autrement dit, une métaclasse est la classe d'une classe.

Généralités

En programmation orientée objet, une classe est une sorte de moule qui permet de créer un sous-ensemble (En mathématiques, un ensemble A est un sous-ensemble ou une partie d’un ensemble B, ou encore B est sur-ensemble de A, si tout élément du sous-ensemble A est aussi élément du...) d'objets. La classe décrit comment se comportent ses objets, fournit leur interface (Une interface est une zone, réelle ou virtuelle qui sépare deux éléments. L’interface désigne ainsi ce que chaque élément a besoin de connaître de...) et compose la structure de leur état. La classe permet de créer de nouveaux objets au moyen d'un mécanisme appelé instanciation. Ce mécanisme peut se décomposer en deux opérations :

  • allocation d'un espace mémoire (D'une manière générale, la mémoire est le stockage de l'information. C'est aussi le souvenir d'une information.) pour le nouvel objet (De manière générale, le mot objet (du latin objectum, 1361) désigne une entité définie dans un espace à trois dimensions, qui a une fonction précise, et...) (opération alloc()),
  • initialisation du nouvel objet (lancement du constructeur).

Dans des environnements de programmation (La programmation dans le domaine informatique est l'ensemble des activités qui permettent l'écriture des programmes informatiques. C'est une étape importante de la conception de logiciel (voire de matériel, cf. VHDL).) réflexifs, les classes peuvent être vues comme des objets à part entière créés au moyen du mécanisme d'instanciation (alloc(); init()). Dans ce cas, toutes les classes peuvent être vues comme des instances créées à la base à partir d'une même classe.

Une classe dont les instances sont des classes se nomme métaclasse (notez que la définition (Une définition est un discours qui dit ce qu'est une chose ou ce que signifie un nom. D'où la division entre les définitions réelles et les...) est récursive). Puisqu'une métaclasse est une classe, elle définit elle aussi le comportement et la structure de l'état de ses instances. En créant une nouvelle métaclasse, on va donc intervenir sur la manière avec laquelle les classes sont créées et donc intervenir sur une partie du langage lui-même. Grâce à un mécanisme comme celui-ci, le développeur (En informatique, un développeur (ou programmeur) est un informaticien qui réalise des logiciels en créant des algorithmes et en les mettant en...) peut ajouter de nouvelles fonctionnalités au langage, comme la possibilité de tracer les appels de méthodes, la possibilité de créer des singletons, la sérialisation (En informatique, la sérialisation (de l'anglais américain serialization, le terme marshalling est souvent employé de façon synonyme) est un processus...) d'objets au format XML, etc.

Les métaclasses dans les langages

Les langages suivants permettent de définir des métaclasses :

  • Python (langage)
  • Smalltalk
  • Ruby (Ruby est un langage de programmation libre. Il est interprété, orienté objet, et multi-paradigme.)
  • Perl 6
  • Objective-C
  • Delphi

La classe java.lang.Class (CLASS (CLS) est un célèbre groupe de l'underground informatique. CLASS a cessé son activité le 8 janvier 2004 et en a profité pour réaliser une...) est une métaclasse dans le langage Java.

Exemple simple

 
 # interception de tous les Attributs pour retourner une valeur par defaut 
 # peut servir pour faire des bouchons par exemple ou restreindre la creation 
 #ou l'acces à des attributs etc 
 class MyMetaClasse(type): 
 """une Metaclasse avec intercepteur: des qu'on fait Maclasse.UnAttribut, 
 name =  UnAttribut, on renvoie une valeur par defaut 
 """ 
 def __getattr__(laClasse, name): 
 return 128 
 #Declarer une classe, c'est instancier une métaclasse. 
 class MaClasse: 
 __metaclass__ = MyMetaClasse   #Lien avec la metaclasse 
 #Ensuite la defintion de la classe continue (....) 
 print MaClasse.x, MaClasse.y 
 #resultats 
 128 128 
 

Autre Exemple

Sous Python, la métaclasse de base est nommée type. Quelque soit l'objet manipulé, l'exécution de monObjet.__class__.__class__ retourne type. La création d'une nouvelle métaclasse se fait en spécialisant type. Les opérations alloc() et init() sont respectivement représentées par les méthodes __new__() et __init__(). __new__() est une méthode de classe qui prend quatre paramètres : la métaclasse elle-même, le nom de la classe instanciée, ses superclasses et un dictionnaire contenant l'ensemble (En théorie des ensembles, un ensemble désigne intuitivement une collection d’objets (les éléments de l'ensemble),...) de ses méthodes et attributs. __init__() est une méthode d'instance. Ses paramètres sont les mêmes que ceux de __new__() hormis le premier qui représente la classe instanciée dans le cas de __init__().

L'exemple ci-dessous montre un exemple d'utilisation d'une métaclasse en Python. Il s'agit d'une métaclasse qui permet de tracer l'appel de méthode.

 
 from types import FunctionType 
 class Tracer(type): 
 def __new__(metacls, name, bases, dct): 
 # définition d'une fonction wrapper pour les méthodes 
 def _wrapper(method): 
 # création d'une fonction permettant tracer une méthode 
 def _trace(self, *args, **kwargs): 
 print "(call %s with *%s **%s)" % (method.__name__, str(args), kwargs) 
 return method(self, *args, **kwargs) 
 # idiome: faire passer une fonction pour une autre 
 _trace.__name__ = method.__name__ 
 _trace.__doc__  = method.__doc__ 
 _trace.__dict__.update(method.__dict__) 
 return _trace 
 # remplacement de toutes les méthodes par leur équivalent tracé 
 newDct = {} 
 for name, slot in dct.iteritems(): 
 if type(slot) is FunctionType: 
 newDct[name] = _wrapper(slot) 
 else: 
 newDct[name] = slot 
 # appel au constructeur de la super classe (type) 
 return type.__new__(metacls, name, bases, newDct) 
 

Le principe de la métaclasse Tracer consiste à transformer toutes les méthodes de ses instances, de telle sorte qu'elles affichent un message (La théorie de l'information fut mise au point pour déterminer mathématiquement le taux d’information transmis dans la communication d’un message par un canal de communication, notamment en...) avant de continuer leur exécution. La fonction _wrapper() qui se trouve dans le constructeur de la métaclasse est un décorateur, c'est-à-dire qu'elle prend en entrée une fonction et renvoie en sortie cette fonction avec un comportement modifié. Il faut savoir que dans le paramètre (Un paramètre est au sens large un élément d'information à prendre en compte pour prendre une décision ou pour effectuer un calcul.) dct du constructeur, ce qui doit représenter des méthodes est encore à l'état de fonction.

Voici un exemple montrant comment utiliser la métaclasse.

 
 class A(object): 
 # création de la liaison entre la classe et la métaclasse 
 __metaclass__ = Tracer 
 def __init__(self): 
 self.a = 1 
 def get(self): return self.a 
 (call __new__) 
 >>> a = A() 
 (call __init__) 
 >>> a.get() 
 (call get) 
 1 
 

Voici un exemple en Delphi.

 
 // Voici comment est définit le type TComponentClass dans la VCL de delphi: 
 type 
 TComponentClass=class of TComponent; 
 
Page générée en 0.052 seconde(s) - site hébergé chez Amen
Ce site fait l'objet d'une déclaration à la CNIL sous le numéro de dossier 1037632
Ce site est édité par Techno-Science.net - A propos - Informations légales
Partenaire: HD-Numérique