Конструктор копирования против Cloneable. Почему я не должен рассматривать Cloneable?

Я читал этот ответ, и он упомянул ссылка, где автор объясняет, почему мы не должны использовать Cloneable. Но, до сих пор сомневаюсь, что там было заявлено

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

Но вот я сделал

        Init s = Init.getInstance(); // getting instance
        int count=0;
        Cloneable[] v = new Cloneable[5]; // creating array
        Init x = s;
        Init y = new Init(s);
        try {
            while (count < 5) {
                v[count++] =  (Cloneable) s.clone(); // casting it.
            }

            s.setClassName("Example");
            System.out.println(((Init) v[2]).getClassName()); // Displaying.
        } catch (CloneNotSupportedException ex) {
            ex.printStackTrace();
        }

Мне удалось создать массив Cloneable, и я сделал то, что, по словам автора, вызовет ошибку. Или я неправильно понял заявление автора? Кто-нибудь, пожалуйста, помогите мне понять причину выбора Copy Constructor вместо Cloneable.


person Ravi    schedule 24.07.2015    source источник
comment
Я являюсь разработчиком .net, но концепции oops аналогичны Java и C #. Насколько я понимаю, в конструкторе копирования ссылка на память одинакова как для реального, так и для скопированного объекта. Поэтому, когда вы меняете значение реального объекта, вы увидите, что это также влияет скопированный объект. На клонируемых объектах оба имеют разные ссылки на память, они не зависят друг от друга, они не влияют друг на друга.   -  person Chander .k    schedule 24.07.2015


Ответы (1)


Вы не переводите s в Cloneable, а затем вызываете clone() на нем.

Вместо этого вы вызываете s.clone(), а затем приводите результат к Clonable. Вы можете это сделать, потому что s относится к типу Init, а Init имеет метод public clone().

Сделайте это вместо этого, и вы обнаружите, что компилятор кричит:

 v[count++] =  ((Cloneable) s).clone();

Теперь предположим, что вы хотите клонировать массив (очевидно, вы знаете только, что это массив Cloneable. Это означает, что вы не знаете его фактический тип.

Cloneable[] cloneArray = new Cloneable[5];
cloneArray[i] = new Init(); // Let's say it's initialized with different type objects but all `Cloneable`.

for (Cloneable object : cloneArray) {
      object.clone(); // Compiler wont allow it. And you don't know what type it is.
}

Таким образом, вы в принципе не можете глубоко клонировать массив Cloneable.

person Codebender    schedule 24.07.2015
comment
Это нормально. Но я должен был скопировать его в массив Cloneable. Правильно? Тогда почему бы мне не выбрать Cloneable ? - person Ravi; 24.07.2015
comment
Нет, это означало, что вы не можете клонировать массив Cloneable. Проверьте мой отредактированный ответ. - person Codebender; 24.07.2015
comment
Итак, это единственное, что отличает Copy Constructor от Cloneable? - person Ravi; 24.07.2015