Método clone()
Parte de la sección Programación Orientada a Objetos del Journey de Java de Coddy — lección 43 de 87.
El método clone() crea una copia de un objeto. Para usarlo, su clase debe implementar la interfaz Cloneable y sobrescribir el método clone() de la clase Object.
public class Person implements Cloneable {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public Person clone() {
try {
return (Person) super.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
}Ahora puedes crear copias independientes de objetos:
Person original = new Person("Alice", 25);
Person copy = original.clone();
// copy es un objeto separado con los mismos valoresPor defecto, clone() realiza una copia superficial, lo que significa que copia valores primitivos y referencias. Si su objeto contiene otros objetos como campos, tanto el original como el clon harán referencia a los mismos objetos anidados. Para obtener copias verdaderamente independientes con objetos anidados, necesita implementar una copia profunda clonando también esos objetos anidados dentro de su método clone().
Desafío
FácilConstruyamos un sistema de gestión de documentos que demuestre la clonación de objetos. Crearás una clase Document que se puede clonar para crear copias independientes, permitiendo a los usuarios duplicar documentos manteniendo intacto el original.
Organizarás tu código en dos archivos:
Document.java: Crea una clase que represente un documento que admita la clonación. Un Document tiene tres campos privados:title(String),author(String) yversion(int). Incluye un constructor para inicializar todos los campos y métodos getter para cada uno. También añade un métodosetVersion(int version)para actualizar el número de versión.Haz que tu clase Document implemente la interfaz
Cloneabley sobrescriba el métodoclone()para devolver unDocument. Maneja laCloneNotSupportedExceptiondentro del método envolviéndola en unaRuntimeException.Sobrescribe
toString()para devolver:Document[title=X, author=Y, version=Z]donde X, Y y Z son los valores reales de los campos.Main.java: Da vida a tu clase Document creando un documento y clonándolo. Recibirás tres entradas: un título (String), un autor (String) y un número de versión (int).Crea un Document original con estos valores, luego clónalo para crear una copia. Después de clonar, modifica la versión de la copia incrementándola en 1 usando
setVersion(). Esto demuestra que el clon es verdaderamente independiente del original.Imprime tres líneas:
Original:seguido del toString() del documento originalClone:seguido del toString() del documento clonadoIndependent:seguido detrueofalseindicando si el original y el clon son objetos diferentes (usa la comparación!=)
Recibirás tres entradas: el título del documento (String), el nombre del autor (String) y el número de versión (int).
Observa cómo después de modificar la versión del clon, el documento original permanece sin cambios; ¡esto demuestra que clone() creó una copia verdaderamente independiente!
Hoja de referencia
El método clone() crea una copia de un objeto. Para usarlo, su clase debe implementar la interfaz Cloneable y sobrescribir el método clone() de la clase Object:
public class Person implements Cloneable {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public Person clone() {
try {
return (Person) super.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
}Creación de copias independientes:
Person original = new Person("Alice", 25);
Person copy = original.clone();
// copy is a separate object with the same valuesPor defecto, clone() realiza una copia superficial (shallow copy), copiando valores primitivos y referencias. Si su objeto contiene otros objetos como campos, tanto el original como el clon harán referencia a los mismos objetos anidados. Para obtener copias verdaderamente independientes con objetos anidados, implemente una copia profunda (deep copy) clonando también esos objetos anidados dentro de su método clone().
Pruébalo tú mismo
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Leer entradas
String title = scanner.nextLine();
String author = scanner.nextLine();
int version = scanner.nextInt();
// TODO: Crear un Documento original con los valores de entrada
// TODO: Clonar el documento original para crear una copia
// TODO: Modificar la versión del clon incrementándola en 1
// TODO: Imprimir "Original: " seguido del documento original
// TODO: Imprimir "Clone: " seguido del documento clonado
// TODO: Imprimir "Independent: " seguido de true/false (verificar si original != clon)
}
}Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación Orientada a Objetos
1Fundamentos de OOP
Archivos externosIntroducción a la OOPClases vs. ObjetosLa palabra clave thisMétodosCampos (Atributos)Método constructorSobrecarga de constructoresResumen - Calculadora simple4Herencia
Herencia básica (extends)La palabra clave superSobrescritura de métodos (@Override)Encadenamiento de constructoresLa clase ObjectHerencia simple y multinivelPor qué no hay herencia múltiple de clasesResumen - Jerarquía de empleados7Métodos especiales y la clase Object
Método toString()equals() y hashCode()Método clone()compareTo() y ComparableInterfaz ComparatorResumen - Ordenamiento personalizado2Modificadores de acceso y encapsulamiento
Visión general de los niveles de accesoMétodos Getter y SetterOcultamiento de informaciónLa palabra clave finalResumen - Gestor de cuentas bancarias5Polimorfismo
Fundamentos de sobrecarga de métodosSobrescritura de métodos (tiempo de ejecución)Upcasting y DowncastingEl operador instanceofClases y métodos abstractosResumen - Calculadora de figuras8Conceptos avanzados de POO
Composición vs. HerenciaAgregación vs. ComposiciónClases internas, anidadas y anónimasEnums y métodos de EnumRecords (Java 16+)Clases selladas (Java 17+)11Patrones de diseño - Parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón BuilderPatrón ObserverPatrón Strategy3Propiedades de clase y miembros estáticos
Variables de instancia vs. estáticasMétodos estáticosBloques estáticosConstantes (static final)Repaso - Contador y utilidad6Interfaces y Clases Abstractas
Introducción a las InterfacesImplementación de InterfacesImplementación de Múltiples InterfacesMétodos Default y Static en InterfacesClases Abstractas vs InterfacesInterfaces FuncionalesResumen - Sistema de Pagos9Genéricos
Introducción a los genéricosClases genéricasMétodos genéricosParámetros de tipo delimitadosComodines (?, extends, super)Resumen - Contenedor genérico12Patrones de diseño Parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón CompositePatrón Iterator