Философия Java


Конструкторы копирования - часть 3


Вторая причина размещения FruitQualities в отдельных объектах заключается в добавлении или изменении их при помощи механизмов наследования и полиморфизма. Заметьте что для объекта GreenZebra (зеленая зебра), который на самом деле происходит от типа Tomato. Конструктор вызывает метод addQualities() и передает их ZebraQualities объекту, который наследуется от FruitQualities и поэтому он может быть подключен к ссылке на FruitQualities в базовом классе. Разумеется, когда GreenZebra использует FruitQualities, он должен привести его к нужному типу (как показано в evalute()), но при этом всегда знает что работает с классом ZebraQualities.

Как вы видите, есть еще класс Seed (семя) и класс Fruit (который по определению содержит свои собственные семена)[82], содержит массив из объектов Seeds.

И, наконец, обратите внимание на то что для обеспечения глубокого копирования все классы имеют конструкторы копирования, и каждый конструктор копирования должен позаботиться о том, чтобы вызвать конструкторы копирования для базового класса и объектов-членов. Конструктор копирования тестируется внутри класса CopyConstructor. Метод ripen() получает в качестве параметра Tomato и осуществляет создание его копии.

t = new Tomato(t);

Тем временем slice() получает объект Fruit и также дублирует его:

f = new Fruit(f);

Таким образом в main() тестируются различные экземпляры Fruit. Вот результаты:

В зрелых t это Tomato В нарезаных ломтиками f это Fruit В зрелых t это Tomato В нарезаных ломтиками f это Fruit

Вот где появляются проблемы. После того как создается копия Tomato в slice(), в результате этой операции Tomato перестает существовать, остается только Fruit. Он теряет, так сказать, всю свою "помидорность". Затем, когда дойдет очередь до GreenZebra, ripen() и slice() также превратят его сначала в Tomato, а затем в Fruit. Поэтому, увы, методика конструкторов копирования не применима для Java, когда заходит речь о создании локальных копий.

Почему это работает в C++ и не работает в Java?

Конструкторы копирования - фундаментальный элемент языка Си++, поскольку с их помощью автоматически создаются локальные копии объектов. Однако, как показывает приведенный выше пример, они не работают в Java. Почему? В Java мы можем манипулировать только с ссылками, тогда как в Си++ наряду с аналогами ссылок допускаются манипуляции непосредственно с самими объектами. Вот для чего нужны конструкторы копирования в Си++: они создают дубликат объекта в случаях когда требуется передать объект "по значению". Этот прием прекрасно работает в Си++, но вы должны помнить что такая конструкция не будет работать в Java и должны воздержаться от ее использования.




Начало  Назад  Вперед



Книжный магазин