Traiter les classes comme des objets de première classe
-
03-07-2019 - |
Question
Je lisais le livre GoF et au début de la section prototype, je lisais ceci:
Cet avantage s'applique principalement aux langages comme C ++ qui ne traitent pas classes en tant qu'objets de première classe.
Je n’ai jamais utilisé le C ++, mais j’ai une assez bonne compréhension de la programmation orientée objet, mais cela n’a aucun sens pour moi. Quelqu'un peut-il élaborer sur ce sujet (j'ai utilisé \ use: C, Python, Java, SQL si cela peut aider.)
La solution
Pour qu'une classe soit un objet de première classe, le langage doit permettre d'effectuer des opérations telles que permettre aux fonctions de prendre des classes (et non des instances) comme paramètres, de pouvoir contenir des classes dans des conteneurs et de pouvoir renvoyer des classes à partir de fonctions.
Pour un exemple de langage avec des classes de première classe, considérons Java. Tout objet est une instance de sa classe. Cette classe est elle-même une instance de java.lang. Classe .
Autres conseils
Pour tout le monde, voici la citation complète:
"Sous-classement réduit. Méthode d'usine (107) produit souvent une hiérarchie de Classes de créateurs parallèles à la hiérarchie des classes de produits. Le Prototype motif vous permet de cloner un prototype au lieu de demander à une méthode d'usine de faire un nouvel objet. Donc vous ne besoin d'une hiérarchie de classe Creator du tout. Cet avantage s'applique principalement aux langages comme C ++ qui ne traitent pas classes en tant qu'objets de première classe. Les langues qui font, comme Smalltalk et Objectif C, retirer moins d'avantages, puisque tu peux toujours utiliser une classe objet en tant que créateur. Objets de classe agissent déjà comme des prototypes dans ces langues. " - GoF, page 120.
As Steve met il ,
Je l'ai trouvé subtil dans la mesure où aurait pu le comprendre comme impliquant que / instances / de classes ne sont pas traité des objets de première classe en C ++. Si les mêmes mots utilisés par GoF sont apparus dans un cadre moins formel, ils peuvent bien eu l'intention / instances / plutôt que les classes. La distinction ne peut pas semble subtil pour / vous /. / I /, cependant, eu à y réfléchir un peu.
Je crois que la distinction est important. Si je ne me trompe pas, là n'est pas obligatoire qu'un C ++ compilé programme préserver tout artefact par lequel la classe à partir de laquelle un objet est créé pourrait être reconstruit. IOW, d'utiliser la terminologie Java, il n'y a pas / Classe / objet.
En Java, chaque classe est un objet en soi, dérivé de java.lang.Class, qui vous permet d’accéder aux informations sur cette classe, ses méthodes, etc. à partir du programme. C ++ n'est pas comme ça; les classes (par opposition à leurs objets) ne sont pas vraiment accessibles au moment de l'exécution. Il existe une installation appelée RTTI (Informations de type à l'exécution) qui vous permet de faire certaines choses dans ce sens, mais elle est assez limitée et entraîne des coûts de performance.
Vous avez utilisé python, un langage avec des classes de première classe. Vous pouvez passer une classe à une fonction, la stocker dans une liste, etc. Dans l'exemple ci-dessous, la fonction new_instance () renvoie une nouvelle instance de la classe à laquelle elle est transmise.
class Klass1:
pass
class Klass2:
pass
def new_instance(k):
return k()
instance_k1 = new_instance(Klass1)
instance_k2 = new_instance(Klass2)
print type(instance_k1), instance_k1.__class__
print type(instance_k2), instance_k2.__class__
Les programmes C # et Java peuvent connaître leurs propres classes, car les environnements d'exécution .NET et Java fournissent réflexion , qui permet en général à un programme d’avoir des informations sur sa propre structure (à la fois en .NET et en Java, cette structure se trouve être en termes de classes).
Il n’est pas possible de se permettre une réflexion sans s’appuyer sur un environnement d’exécution, car un programme ne peut pas prendre conscience de lui-même *. Mais si l'exécution de votre programme est gérée par un environnement d'exécution, celui-ci peut alors disposer d'informations sur lui-même à partir de l'exécution. C ++ étant compilé en code natif non géré, vous ne pouvez vous permettre une réflexion en C ++ **.
...
* Eh bien, il n'y a aucune raison pour qu'un programme ne puisse pas lire son propre code machine et "essayer de tirer des conclusions". sur lui-même. Mais je pense que c'est quelque chose que personne ne voudrait faire.
** Pas strictement exact. En utilisant d'horribles hacks basés sur des macros, vous pouvez obtenir quelque chose de similaire à la réflexion tant que votre hiérarchie de classes a une seule racine. MFC en est un exemple.
La métaprogrammation des modèles a offert au C ++ plus de moyens de jouer avec les classes, mais pour être honnête, je ne pense pas que le système actuel permette à toutes les opérations que les gens souhaitent effectuer (principalement, il n’existe pas de moyen standard de découvrir toutes les méthodes disponibles pour une classe ou un objet). Ce n'est pas un oubli, c'est par conception.