Главная страница
Навигация по странице:

  • 2. Переопределение метода

  • 3. Конструктор копирования

  • Ответы на вопросы по ревью 4. Java io. Ключевым понятием здесь является понятие потока


    Скачать 1.93 Mb.
    НазваниеJava io. Ключевым понятием здесь является понятие потока
    Дата03.07.2022
    Размер1.93 Mb.
    Формат файлаdoc
    Имя файлаОтветы на вопросы по ревью 4.doc
    ТипДокументы
    #623608
    страница28 из 39
    1   ...   24   25   26   27   28   29   30   31   ...   39

    Клонирование

    1. Что такое клонирование?


    Иногда необходимо на основе существующего объекта создать второй такой же - то есть создать его клон. Это процесс в Java называется клонированием.

    Для клонирования объекта в Java можно воспользоваться тремя способами:

    1. Переопределение метода clone() и реализация интерфейса Cloneable().

    2. Использование конструктора копирования.

    3. Использовать для клонирования механизм сериализации.

    2. Переопределение метода clone()


    Класс Object определяет метод clone(), который создает копию объекта. Если вы хотите, чтобы экземпляр вашего класса можно было клонировать, необходимо переопределить этот метод и реализовать интерфейс Cloneable. Интерфейс Clonable - это интерфейс маркер, он не содержит ни методов, ни переменных. Интерфейсы маркер просто определяют поведение классов.

    Object.clone() выбрасывает исключение CloneNotSupportedException при попытке клонировать объект не реализующий интерфейс Cloneable

    Метод clone() в родительском классе Object является protected, поэтому желательно переопределить его как public. Реализация по умолчанию метода Object.clone() выполняет неполное/поверхностное (shallow) копирование. Рассмотрим пример:

    Пример 1. Поверхностное клонирование


    public class Car implements Cloneable {

    private String name;

    private Driver driver;
    public Car(String name, Driver driver) {

    this.name = name;

    this.driver = driver;

    }
    public String getName() {

    return name;

    }
    public void setName(String name) {

    this.name = name;

    }
    public Driver getDriver() {

    return driver;

    }
    public void setDriver(Driver driver) {

    this.driver = driver;

    }
    @Override

    public Car clone() throws CloneNotSupportedException {

    return (Car) super.clone();

    }

    }

    public class Driver implements Cloneable {

    private String name;

    private int age;
    public Driver(String name, int age) {

    this.name = name;

    this.age = age;

    }
    public String getName() {

    return name;

    }
    public void setName(String name) {

    this.name = name;

    }
    public int getAge() {

    return age;

    }
    public void setAge(int age) {

    this.age = age;

    }
    @Override

    public Driver clone() throws CloneNotSupportedException {

    return (Driver) super.clone();

    }

    }

    public class CloneCarDemo {

    public static void main(String[] args) throws CloneNotSupportedException {

    Car car = new Car("Грузовик", new Driver("Василий", 45));

    Car clonedCar = car.clone();

    System.out.println("Оригинал:\t" + car);

    System.out.println("Клон: \t" + clonedCar);
    Driver clonedCarDriver = clonedCar.getDriver();

    clonedCarDriver.setName("Вася");
    System.out.println("Оригинал после изменения имени водителя:\t" + car);

    System.out.println("Клон после изменения имени водителя: \t\t" + clonedCar);

    }

    }

    В этом примере клонируются объект класса Car. Клонирование выполняется поверхностное - новый объект clonedCar содержит ссылку на тот же объект класса Driver, что и объект car. Если вас это не устраивает, то необходимо самим написать "глубокое" клонирование - создать новый объект класса Driver. Перепишем метод clone() класса Car:

    Пример 2. Глубокое клонирование


    @Override

    public Car clone() throws CloneNotSupportedException {

    Car newCar = (Car) super.clone();

    Driver driver = this.getDriver().clone();

    newCar.setDriver(driver);

    return newCar;

    }

    3. Конструктор копирования


    Еще один вариант клонирования объекта - это конструктор копирования. Создается конструктор, принимающий на вход объект того же класса, который необходимо клонировать:

    Пример 3. Конструктор копирования с поверхностным клонированием


    public class Car implements Cloneable {

    private String name;

    private Driver driver;
    public Car(String name, Driver driver) {

    this.name = name;

    this.driver = driver;

    }
    /**

    * Конструктор копирования.

    *

    * @param otherCar

    */

    public Car(Car otherCar) {

    this(otherCar.getName(), otherCar.getDriver());

    }
    public String getName() {

    return name;

    }
    public void setName(String name) {

    this.name = name;

    }
    public Driver getDriver() {

    return driver;

    }
    public void setDriver(Driver driver) {

    this.driver = driver;

    }

    }

    Опять же  - пример показывает неглубокое клонирование. Перепишем конструктор для реализации "глубокого" копирования:

    Пример 4.  Конструктор копирования с "глубоким" клонированием


    public Car(Car otherCar) throws CloneNotSupportedException {

    this(otherCar.getName(), otherCar.getDriver().clone());

    }
    Клонирование объекта создает копию существующего объекта для изменения или перемещения скопированного объекта, не затрагивая исходный объект. В Java управление объектами осуществляется с помощью ссылочных переменных, и нет оператора для фактического копирования объекта. Помните, что оператор присваивания дублирует ссылку, а не объект.
    1   ...   24   25   26   27   28   29   30   31   ...   39


    написать администратору сайта