quase todas as linguagens de programação orientadas a objetos fornecem alguma maneira de copiar objetos. Como a maioria das linguagens não fornecem a maioria dos objetos para Programas, um programador deve definir como um objeto deve ser copiado, assim como eles devem definir se dois objetos são idênticos ou mesmo comparáveis em primeiro lugar. Muitas linguagens fornecem algum comportamento padrão.
Como a cópia é resolvida varia de linguagem para linguagem, e que conceito de um objeto tem.
copyEdit preguiçoso
uma cópia preguiçosa é uma implementação de uma cópia profunda., Ao copiar inicialmente um objeto, uma cópia (rápida) superficial é usada. Um contador também é usado para rastrear quantos objetos compartilham os dados. Quando o programa quer modificar um objeto, ele pode determinar se os dados são compartilhados (examinando o contador) e pode fazer uma cópia profunda se necessário.
cópia preguiçosa olha para o exterior assim como uma cópia profunda, mas aproveita a velocidade de uma cópia rasa sempre que possível. As desvantagens são bastante elevadas, mas os custos de base constantes por causa do contador. Além disso, em certas situações, as referências circulares podem causar problemas.
Lazy copy is related to copy-on-write.,
em JavaEdit
a seguir apresenta exemplos para uma das linguagens mais amplamente usadas orientadas a objetos, Java, que deve cobrir quase todas as formas que uma linguagem orientada a objetos pode tratar este problema.
Ao contrário de C++, objetos em Java são sempre acessados indiretamente através de referências. Objetos nunca são criados implicitamente, mas em vez disso são sempre passados ou atribuídos por uma variável de referência. (Métodos em Java são sempre passados por valor, no entanto, é o valor da variável de referência que está sendo passada., A máquina virtual Java gerencia a coleta de lixo para que os objetos sejam limpos depois de não serem mais acessíveis. Não existe uma maneira automática de copiar qualquer objeto dado em Java.
copiar é geralmente realizado por um método clone() de uma classe. Este método geralmente, por sua vez, chama o método clone() de sua classe-mãe para obter uma cópia, e então faz quaisquer procedimentos de cópia personalizados., Eventualmente isso chega ao método clone() de Object
(a classe mais alta), que cria uma nova instância da mesma classe que o objeto e copia todos os campos para a nova instância (uma “cópia rasa”). Se este método for usado, a classe deve implementar o Cloneable
interface de marcação, ou então ele irá lançar um CloneNotSupportedException. Depois de obter uma cópia da classe-mãe, um método clone próprio da classe pode então fornecer capacidade de clonagem personalizada, como cópia profunda (i.e., duplicar algumas das estruturas referidas pelo objeto) ou dar à nova instância um novo ID único.
the return type of clone() is Object
, but implementers of a clone method could write the type of the object being cloned instead due to Java’s support for covariant return types. Uma vantagem de usar o clone () é que, uma vez que ele é um método overridable, nós podemos chamar clone() em qualquer objeto, e ele vai usar o método clone() de sua classe, sem o código de chamada que precisa saber o que essa classe é (que seria necessário com um construtor de cópia).,
uma desvantagem é que muitas vezes não se pode acessar o método clone() em um tipo abstrato. A maioria das interfaces e classes abstratas em Java não especificam um método de clone público (). Assim, muitas vezes a única maneira de usar o método clone() é se a classe de um objeto é conhecida, o que é contrário ao princípio de abstração de usar o tipo mais genérico possível. Por exemplo, se alguém tem uma referência de lista em Java, não se pode invocar clone() nessa referência porque a lista não especifica nenhum método de clone público ()., Implementações de listas como ArrayList e LinkedList geralmente têm métodos de clone (), mas é inconveniente e má abstração carregar em torno do tipo de classe de um objeto.
outra maneira de copiar objetos em Java é serializá-los através da interface
. Isso normalmente é usado para persistência e o fio de protocolo de fins, mas ele não cria cópias de objetos e, ao contrário do clone, uma cópia profunda que processa ciclo gráficos de objetos é prontamente disponível com o mínimo de esforço a partir de um programador.,
ambos os métodos sofrem de um problema notável: o construtor não é usado para objetos copiados com clone ou serialização. Isso pode levar a bugs com dados mal inicializados, impede o uso de final
campos membros, e torna a manutenção desafiadora. Alguns utilitários tentam superar essas questões usando a reflexão para copiar objetos profundos, como a biblioteca de clonagem profunda.,
In eiffeledit
Runtime objects in Eiffel are accessible either indiretamente through references or as expanded objects which fields are embedded within the objects that use them. Ou seja, os campos de um objeto são armazenados externamente ou internamente.
A classe Eiffel ANY
contém características para cópia superficial e profunda e clonagem de objetos. Todas as classes Eiffel herdam de ANY
, de modo que estas características estão disponíveis dentro de todas as classes, e são aplicáveis tanto aos objetos de referência e expandidos.,
The copy
feature effects a shallow, field-by-field copy from one object to another. Neste caso, nenhum novo objeto é criado. Se y
foram copiados para o x
e, em seguida, os mesmos objetos referenciados por y
antes da aplicação de copy
, irá também ser referenciado por x
depois copy
funcionalidade completa.,
para efetuar a criação de um novo objeto que é um duplicado raso de y
, a característica twin
é usada. Neste caso, um novo objeto é criado com seus campos idênticos aos da fonte.
O recurso twin
depende o recurso de copy
, que pode ser redefinido no descendentes de ANY
, se necessário. O resultado de twin
é do tipo ancoradolike Current
.,
copiar profundamente e criar gêmeos profundos pode ser feito usando as características deep_copy
e deep_twin
, novamente herdado da classe ANY
. Essas características têm o potencial de criar muitos objetos Novos, porque eles duplicam todos os objetos em uma estrutura de objeto inteiro. Como novos objetos duplicados são criados em vez de simplesmente copiar referências a objetos existentes, operações profundas se tornarão uma fonte de problemas de desempenho mais facilmente do que operações rasas.,
in other languagesEdit
In C#, rather than using the interface ICloneable
, a generic extension method can be used to create a deep copy using reflection. Isso tem duas vantagens: Primeiro, ele oferece a flexibilidade para copiar cada objeto sem ter que especificar cada propriedade e variável a ser copiada manualmente. Em segundo lugar, porque o tipo é genérico, o compilador garante que o objeto de destino e o objeto fonte têm o mesmo tipo.,
no Objective-C, os métodos copy
emutableCopy
são herdados por todos os objetos e destinados a realizar cópias; este último é para criar um tipo mutável do objeto original. Estes métodos por sua vez chamam o id
emutableCopyWithZone
métodos, respectivamente, para realizar a cópia. Um objeto deve implementar o correspondente métodocopyWithZone
para ser copiável.em OCaml, a função da biblioteca Oo.o copy efectua uma cópia rasa de um objecto.,
em Ruby, todos os objetos herdam dois métodos para realizar cópias rasas, clone e dup. Os dois métodos diferem no que clone
cópias de um objeto contaminado estado, estado congelado, e qualquer singleton métodos que podem ter, enquanto dup
copia apenas o seu ” tainted estado. Cópias profundas podem ser obtidas por vazamento e carregamento de um fluxo de bytes de um objeto ou serialização YAML. Alternativamente, você pode usar a gema deep_dive para fazer uma cópia controlada de seus gráficos de objetos.,
em Perl, estruturas aninhadas são armazenadas pelo uso de referências, assim, um desenvolvedor pode tanto loop sobre toda a estrutura e re-referenciar os dados ou usar a função
a partir do módulo armazenável.
Em VBA, uma atribuição de variáveis do tipo Object
é uma cópia superficial, uma atribuição para todos os outros tipos (tipos numéricos, de Cadeia, tipos definidos pelo usuário, matrizes) é uma cópia de profundidade. Assim, a palavra-chave Set
para uma atribuição sinaliza uma cópia rasa e a palavra-chave (opcional) Let
sinaliza uma cópia profunda., Não há nenhum método embutido para cópias profundas de objetos em VBA.
Deixe uma resposta