class MyObjs{
// Поля класса:
double Re,Im;
// Присваивание значений полям:
void set(double Re,double Im){
this.Re=Re;
this.Im=Im;
show();}
// Отображение значений полей:
void show(){
System.out.println("Re="+Re+" и "+"Im="+Im);}
// Конструктор без аргументов:
MyObjs(){
set(0,0);}
// Конструктор с одним аргументом:
MyObjs(double x){
set(x,x);}
// Конструктор с двумя аргументами:
MyObjs(double x,double y){ set(x,y);}
// Конструктор копирования:
MyObjs(MyObjs obj){
set(obj.Re,obj.Im);}
// Аргумент и результат - объекты:
MyObjs getSum(MyObjs obj){
// Создание локального объекта:
MyObjs tmp=new MyObjs();
// Определение параметров локального объекта:
tmp.Re=Re+obj.Re;
tmp.Im=Im+obj.Im;
// Возвращение результата методом:
return tmp;}
// "Прибавление" объекта к объекту:
void add(MyObjs obj){
Re+=obj.Re;
Im+=obj.Im;}
}
class ObjsDemo{
public static void main(String[] args){
// Создание объектов:
MyObjs a=new MyObjs(1);
MyObjs b=new MyObjs(-3,5);
MyObjs c=new MyObjs(b);
// Вычисление "суммы" объектов:
c=a.getSum(b);
// Проверка результата:
c.show();
// Изменение объекта:
a.add(c);
// Проверка результата:
a.show();
} }
Класс MyObjs имеет два поля Re и Im, метод set() с двумя аргументами для присваивания значений полям, метод show() для отображения значений полей объектов, а также метод getSum(), с помощью которого вычисляется «сумма» двух объектов. В результате выполнения метода создается объект, причем значения его полей равны сумме соответствующих полей объекта, из которого вызывается метод, и объекта, переданного методу в качестве аргумента. В отличие от этого метода, методом add() изменяется объект, из которого вызывается метод, а результат методом add() не возвращается. Действие метода add() состоит в том, что к полям объекта, из которого вызывается метод, прибавляются значения соответствующих полей объекта-аргумента метода.
В методе getSum() командой MyObjs tmp=new MyObjs() создается локальный (доступный только в пределах метода) объект tmp класса MyObjs. При создании объекта использован конструктор без аргументов, поэтому при создании объект tmp получает нулевые значения для полей, хотя это и не принципиально. Командами tmp.Re=Re+obj.Re и tmp.Im=Im+obj.Im полям tmp.Re и tmp.Im созданного объекта присваиваются нужные значения — суммы соответствующих полей объекта, из которого вызывается метод (поля Re и Im), и полей объекта obj, переданного аргументом методу (поля obj.Re и obj.Im). После того как для локального объекта tmp заданы все свойства, этот объект командой return tmp возвращается в качестве результата.
Для понимания принципов работы метода следует учесть особенности возвращения объекта в качестве результата. Так, если методом возвращается объект, при выполнении метода выделяется место в памяти для записи результата. Этот процесс (выделение места в памяти) не следует путать с созданием объекта. После того как в методе выполнена инструкция возврата значения, локальный объект, используемый как результат метода, копируется в место, выделенное в памяти для результата. Ссылка на эту область памяти фактически и является тем значением, которое присваивается переменной, указанной слева от оператора присваивания в команде вызова метода (как, например, в команде c=a. getSum(b) метода main()).
В методе add() командами Re+=obj.Re и Im+=obj.Im изменяются поля Re и Im того объекта, из которого вызывается метод. Поэтому хотя метод результата не возвращает, после его выполнения объект, из которого вызывается метод, изменяется.
Кроме перечисленных методов в классе описаны четыре конструктора, позволяющие создавать объекты без передачи аргумента, с передачей одного аргумента, с передачей двух аргументов, и конструктор копирования. Имеет смысл остановиться на последнем случае.
Аргументом конструктора копирования указывается объект того же класса. В результате создается копия этого объекта. Что касается технической реализации всех конструкторов, то применен следующий прием. В классе, как отмечалось, описан метод set(), которому передаются два аргумента и который позволяет присвоить полям соответствующие значения. В конструкторах этот метод вызывается с аргументами в зависимости от того, какие аргументы передаются конструктору. Так, если конструктору аргументы не передаются, метод set() вызывается с нулевыми аргументами. Для конструктора с одним аргументом метод set() вызывается с двумя одинаковыми аргументами. Если конструктору переданы два аргумента, эти же аргументы передаются методу set(). В конструкторе копирования аргументами метода set() указываются соответствующие поля объекта-аргумента конструктора. Такой подход нередко облегчает процесс создания эффективного программного кода. Например, в случаях когда каждый конструктор должен содержать стандартный блок команд, эти команды могут быть вынесены в отдельный метод, который затем вызывается в конструкторе.
В результате выполнения программы мы получаем последовательность сообщений:
Re=1.0 и Im=1.0
Re=-3.0 и Im=5.0
Re=-3.0 и Im=5.0
Re=0.0 и Im=0.0
Re=-2.0 и Im=6.0
Re=-1.0 и Im=7.0
Каждый раз при создании объекта выводится сообщение со значениями полей созданного объекта. Думается, причина появления каждого сообщения понятна, исходя из структуры программы. Интерес может представлять разве что четвертая строка, в которой выводится сообщение с нулевыми значениями полей. Она появляется вследствие создания локального объекта tmp в методе getSum().
Рассмотрим еще один пример, иллюстрирующий способ использования анонимных объектов в качестве аргументов конструктора. Код соответствующей программы приведен в листинге 5.6.