Menu
Coddy logo textTech

Метод clone()

Часть раздела Объектно-ориентированное программирование путешествия по Java на Coddy — урок 43 из 87.

Метод clone() создает копию объекта. Чтобы использовать его, ваш класс должен реализовать интерфейс Cloneable и переопределить метод clone() из класса 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);
        }
    }
}

Теперь вы можете создавать независимые копии объектов:

Person original = new Person("Alice", 25);
Person copy = original.clone();
// copy — это отдельный объект с теми же значениями

По умолчанию clone() выполняет поверхностное копирование, что означает копирование примитивных значений и ссылок. Если ваш объект содержит другие объекты в качестве полей, и оригинал, и клон будут ссылаться на одни и те же вложенные объекты. Для создания по-настоящему независимых копий с вложенными объектами вам необходимо реализовать глубокое копирование, также клонируя эти вложенные объекты внутри вашего метода clone().

challenge icon

Задание

Легко

Давайте создадим систему управления документами, которая демонстрирует клонирование объектов. Вы создадите класс Document, который можно клонировать для создания независимых копий, что позволит пользователям дублировать документы, сохраняя оригинал нетронутым.

Вы организуете свой код в двух файлах:

  • Document.java: Создайте класс, представляющий документ, который поддерживает клонирование. Document имеет три приватных поля: title (String), author (String) и version (int). Включите конструктор для инициализации всех полей и методы-геттеры для каждого из них. Также добавьте метод setVersion(int version) для обновления номера версии.

    Сделайте так, чтобы ваш класс Document реализовывал интерфейс Cloneable и переопределял метод clone() для возврата Document. Обработайте исключение CloneNotSupportedException внутри метода, обернув его в RuntimeException.

    Переопределите toString(), чтобы он возвращал: Document[title=X, author=Y, version=Z], где X, Y и Z — это фактические значения полей.

  • Main.java: Оживите ваш класс Document, создав документ и клонировав его. Вы получите три входных значения: заголовок (String), автора (String) и номер версии (int).

    Создайте оригинальный Document с этими значениями, затем клонируйте его, чтобы создать копию. После клонирования измените версию копии, увеличив ее на 1 с помощью setVersion(). Это продемонстрирует, что клон действительно независим от оригинала.

    Выведите три строки:

    1. Original: за которым следует toString() оригинального документа
    2. Clone: за которым следует toString() клонированного документа
    3. Independent: за которым следует true или false, указывающее, являются ли оригинал и клон разными объектами (используйте сравнение !=)

Вы получите три входных значения: заголовок документа (String), имя автора (String) и номер версии (int).

Обратите внимание, как после изменения версии клона оригинальный документ остается неизменным — это доказывает, что clone() создал по-настоящему независимую копию!

Шпаргалка

Метод clone() создает копию объекта. Чтобы использовать его, ваш класс должен реализовать интерфейс Cloneable и переопределить метод clone() из класса 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);
        }
    }
}

Создание независимых копий:

Person original = new Person("Alice", 25);
Person copy = original.clone();
// copy — это отдельный объект с теми же значениями

По умолчанию clone() выполняет поверхностное копирование, копируя примитивные значения и ссылки. Если ваш объект содержит другие объекты в качестве полей, и оригинал, и копия будут ссылаться на одни и те же вложенные объекты. Для создания по-настоящему независимых копий с вложенными объектами реализуйте глубокое копирование, также клонируя эти вложенные объекты внутри вашего метода clone().

Попробуйте сами

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Чтение входных данных
        String title = scanner.nextLine();
        String author = scanner.nextLine();
        int version = scanner.nextInt();
        
        // TODO: Создать оригинальный Document с входными значениями
        
        // TODO: Клонировать оригинальный документ, чтобы создать копию
        
        // TODO: Изменить версию клона, увеличив её на 1
        
        // TODO: Вывести "Original: " и следом оригинальный документ
        
        // TODO: Вывести "Clone: " и следом клонированный документ
        
        // TODO: Вывести "Independent: " и следом true/false (проверить, что original != clone)
        
    }
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование