presque tous les langages de programmation orientés objet fournissent un moyen de copier des objets. Comme la plupart des langages ne fournissent pas la plupart des objets pour les programmes, un programmeur doit définir comment un objet doit être copié, tout comme il doit définir si deux objets sont identiques ou même comparables en premier lieu. De nombreuses langues fournissent un comportement par défaut.
comment la copie est résolue varie d’une langue à l’autre, et quel concept d’un objet il a.
Lazy copyEdit
Une copie paresseuse est une implémentation d’une copie profonde., Lors de la copie initiale d’un objet, une copie (rapide) peu profonde est utilisée. Un compteur est également utilisé pour suivre le nombre d’objets qui partagent les données. Lorsque le programme veut modifier un objet, il peut déterminer si les données sont partagées (en examinant le compteur) et peut faire une copie profonde si nécessaire.
Paresseux copie regarde vers l’extérieur comme une copie en profondeur, mais prend avantage de la vitesse d’une copie à chaque fois que possible. Les inconvénients sont des coûts de base plutôt élevés mais constants à cause du compteur. Aussi, dans certaines situations, les références circulaires peuvent causer des problèmes.
la copie paresseuse est liée à la copie sur écriture.,
dans JavaEdit
ce qui suit présente des exemples pour L’un des langages orientés objet les plus utilisés, Java, qui devrait couvrir presque toutes les manières dont un langage orienté objet peut traiter ce problème.
contrairement à C++, Les objets en Java sont toujours accessibles indirectement via des références. Les objets ne sont jamais créés implicitement mais sont toujours transmis ou affectés par une variable de référence. (Méthodes en Java sont toujours le passage par valeur, cependant, il est la valeur de la variable de référence est passée.,) La machine virtuelle Java gère la récupération de place afin que les objets soient nettoyés après qu’ils ne soient plus accessibles. Il n’y a pas de moyen automatique de copier un objet donné en Java.
la Copie est généralement effectuée par une méthode clone() de la classe. Cette méthode appelle généralement à son tour la méthode clone () de sa classe parente pour obtenir une copie, puis effectue toutes les procédures de copie personnalisées., Finalement, cela arrive à la méthode clone () de Object
(la classe la plus haute), qui crée une nouvelle instance de la même classe que l’objet et copie tous les champs dans la nouvelle instance (une « copie superficielle »). Si cette méthode est utilisée, la classe doit implémenter l’interface de marqueurCloneable
, sinon elle lancera une CloneNotSupportedException. Après avoir obtenu une copie de la classe parente, la propre méthode clone() d’une classe peut alors fournir une capacité de Clonage personnalisée, comme la copie profonde (c’est-à-dire, dupliquer certaines des structures référencées par l’objet) ou donner à la nouvelle instance un nouvel ID unique.
le type de retour de clone() est Object
, mais les implémenteurs d’une méthode clone pourraient écrire le type de l’objet cloné à la place en raison de la prise en charge par Java des types de retour covariants. Un avantage de l’utilisation de clone() est que comme il s’agit d’une méthode remplaçable, nous pouvons appeler clone() sur n’importe quel objet, et il utilisera la méthode clone() de sa classe, sans que le code appelant ait besoin de savoir quelle est cette classe (ce qui serait nécessaire avec un constructeur de copie).,
un inconvénient est que l’on ne peut souvent pas accéder à la méthode clone() sur un type abstrait. La plupart des interfaces et des classes abstraites en Java ne spécifient pas de méthode publique clone (). Ainsi, souvent, la seule façon d’utiliser la méthode clone() est que si la classe de l’objet est connu, ce qui est contraire au principe d’abstraction de l’aide le plus générique possible. Par exemple, si L’on a une référence List en Java, on ne peut pas appeler clone() sur cette référence Car List ne spécifie aucune méthode publique clone ()., Les implémentations de List comme ArrayList et LinkedList ont toutes généralement des méthodes clone (), mais il est gênant et mauvais de transporter le type de classe d’un objet.
Une autre façon de copier des objets en Java est de les sérialiser via l’interfaceSerializable
. Ceci est généralement utilisé à des fins de protocole de persistance et de fil, mais il crée des copies d’objets et, contrairement au clone, une copie profonde qui gère gracieusement les graphiques cyclés d’objets est facilement disponible avec un minimum d’effort de la part d’un programmeur.,
ces deux méthodes souffrent d’un problème notable: le constructeur n’est pas utilisé pour les objets copiés avec clone ou sérialisation. Cela peut entraîner des bogues avec des données mal initialisées, empêcher l’utilisation des champs membres final
et rendre la maintenance difficile. Certains utilitaires tentent de résoudre ces problèmes en utilisant la réflexion pour copier en profondeur des objets, tels que la bibliothèque de Clonage en profondeur.,
dans EiffelEdit
Les objets Runtime dans Eiffel sont accessibles soit indirectement via des références, soit sous forme d’objets développés dont les champs sont incorporés dans les objets qui les utilisent. C’est-à-dire que les champs d’un objet sont stockés en externe ou en interne.
la classe EiffelANY
contient des fonctionnalités pour la copie et le clonage superficiels et profonds d’objets. Toutes les classes Eiffel héritent de ANY
, ces fonctionnalités sont donc disponibles dans toutes les classes et sont applicables à la fois aux objets de référence et aux objets développés.,
la fonctionnalitécopy
effectue une copie superficielle, champ par champ, d’un objet à un autre. Dans ce cas, aucun nouvel objet est créé. Si y
ont été copiés dans le x
, puis les mêmes objets référencés par y
avant copy
, sera également référencé par x
après le copy
fonctionnalité complète.,
Pour effet la création d’un nouvel objet qui est un peu doublon de y
, la fonction twin
est utilisé. Dans ce cas, un nouvel objet est créé avec ses champs identiques à ceux de la source.
La fonction twin
s’appuie sur l’élément copy
, qui peuvent être redéfinies dans les descendants de ANY
, si nécessaire. Le résultat de twin
est de la ancré type like Current
.,
la copie profonde et la création de jumeaux profonds peuvent être effectuées en utilisant les fonctionnalitésdeep_copy
etdeep_twin
, encore une fois héritées de la classeANY
. Ces fonctionnalités ont le potentiel de créer de nombreux nouveaux objets, car elles dupliquent tous les objets dans une structure d’objet entière. Étant donné que de nouveaux objets en double sont créés au lieu de simplement copier des références à des objets existants, les opérations profondes deviendront une source de problèmes de performances plus facilement que les opérations superficielles.,
dans d’autres languesedit
en C#, plutôt que d’utiliser l’interfaceICloneable
, une méthode d’extension générique peut être utilisée pour créer une copie profonde en utilisant la réflexion. Cela présente deux avantages: Premièrement, il offre la flexibilité de copier chaque objet sans avoir à spécifier chaque propriété et variable à copier manuellement. Deuxièmement, comme le type est générique, le compilateur s’assure que l’objet destination et l’objet source ont le même type.,
dans Objective-C, les méthodescopy
EtmutableCopy
sont héritées par tous les objets et destinées à effectuer des copies; cette dernière est destinée à créer un type mutable de l’objet d’origine. Ces méthodes appellent à leur tour les méthodes copyWithZone
Et mutableCopyWithZone
, respectivement, pour effectuer la copie. Un objet doit implémenter la méthode copyWithZone
correspondante pour pouvoir être copié.
dans OCaml, la fonction de bibliothèque Oo.copy effectue une copie superficielle d’un objet.,
dans Ruby, tous les objets héritent de deux méthodes pour effectuer des copies superficielles, clone et dup. Les deux méthodes diffèrent en ce que clone
copie l’état contaminé d’un objet, l’état gelé et toutes les méthodes singleton qu’il peut avoir, tandis que dup
copie uniquement son état contaminé. Les copies profondes peuvent être obtenues en vidant et en chargeant le flux d’octets d’un objet ou la sérialisation YAML. Vous pouvez également utiliser la gemme deep_dive pour effectuer une copie en profondeur contrôlée de vos graphiques d’objets.,
en Perl, les structures imbriquées sont stockées par l’utilisation de références, ainsi un développeur peut soit faire une boucle sur toute la structure et re-référencer les données ou utiliser la fonctiondclone()
à partir du module stockable.
dans VBA, une affectation de variables de typeObject
est une copie superficielle, une affectation pour tous les autres types (types numériques, chaîne, types définis par l’utilisateur, tableaux) est une copie profonde. Ainsi, le mot-clé Set
pour une affectation signale une copie peu profonde et le mot-clé (facultatif) Let
signale une copie profonde., Il n’y a pas de méthode intégrée pour les copies profondes d’objets dans VBA.
Laisser un commentaire