Ключевое слово this

 

Ключевое слово this является стандартной ссылкой на объект, из которого вы­зывается метод. При этом следует учесть, что в Java ссылка на объект фактиче­ски является именем этого объекта. Хотя наличие такой ссылки может на первый взгляд показаться излишним, она достаточно часто используется на практике. Условно можно выделить два типа ситуаций, когда может потребоваться ссылка this: если она реально необходима и если благодаря ей улучшается читабель­ность программного кода. Примеры первого типа приводятся в последующих главах книги — для их понимания необходимо сначала познакомиться с особен­ностями выполнения ссылок на объекты, способами передачи аргументов мето­дам и механизмом возвращения методом объекта в качестве результата. Здесь же мы приведем примеры использования ключевого слова this в «косметических» целях.

В рассматривавшихся ранее примерах ссылки на члены класса в теле методов этого же класса выполнялись простым указанием имени соответствующего члена. Если для класса создается объект и из этого объекта вызывается метод, то об­ращение к члену класса в программном коде метода означает обращение к со­ответствующему члену объекта. В то же время обращение к полям и методам объекта выполняется в «точечном» синтаксисе, то есть указывается имя объек­та, точка и затем имя поля или метода. Для упомянутой ситуации это означает, что в методе объекта выполняется обращение к члену того же объекта. Этот замечательный факт можно отразить в программном коде метода в явном виде с помощью ссылки this. Пример приведен в листинге 4.5.

Листинг 4.5. Использование ссылки this

class MyClass{

// Поля класса:

double Re,Im;

void set(double Re,double Im){

// Использование ссылки this:

this.Re=Re;

this.Im=Im;}

void get(){

// Инструкция перехода на новую строку \n:

System.out.println("Значения полей:\nRe="+this.Re+" и Im="+this.Im);}

}

class ThisDemo{

public static void main(String[] args){

MyClass obj=new MyClass();

obj.set(1,5);

obj.get();}

}

В данном случае класс MyClass содержит всего два поля Re и Im типа double. Кста­ти, обращаем внимание, что оба поля объявлены одной инструкцией, в которой указан тип полей, а сами поля перечислены через запятую. Данный класс яв­ляется очень слабой аналогией реализации комплексных чисел, у которых есть действительная (поле Re) и мнимая (поле Im) части.

Кроме двух полей, у класса имеется два метода: метод set() для присваивания значений полям и метод get() для отображения значений полей. У метода set() два аргумента типа double, причем их названия совпадают с названиями полей класса. Разумеется, в таком экстремизме необходимости нет, вполне можно было предложить иные названия для аргументов, но мы не ищем простых пу­тей, поэтому сложившаяся ситуация далеко не однозначна. Если в теле мето­да set() использовать обращение Re или Im, то это будет ссылка на аргумент метода, а не на поле класса, поскольку в случае совпадения имен переменных приоритет имеет локальная переменная (то есть объявленная в блоке, в кото­ром находится инструкция вызова переменных с совпадающими именами). Из ситуации выходим, воспользовавшись ссылкой this. Так, инструкции this.Re и this.Im означают поле Re и поле Im соответственно объекта this, то есть того объекта, из которого вызывается метод set() . При этом инструкции Re и Im яв­ляются обращениями к аргументам метода. Поэтому, например, команду this. Re=Re следует понимать так: полю Re объекта this (объекта, из которого вызыва­ется метод set() ) присвоить значение аргумента Re, то есть первого аргумента, переданного методу set() при вызове. Хотя описанная ситуация вполне оправ­дывает использование ссылки this, все же такой прием считается несколько ис­кусственным, поскольку в запасе всегда остается возможность просто поменять названия аргументов.

Совсем неоправданным представляется использование ссылки this в программ­ном коде метода get() , который выводит сообщение со значениями полей объекта. В данном случае инструкции вида this.Re и this.Im можно заменить простыми обращениями Re и Im соответственно — функциональность кода не изменится. У метода аргументов нет вообще, поэтому никаких неоднозначно­стей не возникает. По большому счету, обращение к полю класса (или методу) по имени является упрощенной формой ссылки this (без применения самого ключевого слова this). Этой особенностью синтаксиса языка Java мы пользо­вались ранее и будем пользоваться в дальнейшем. Тем не менее в некоторых случаях указание ссылки this даже в «косметических» целях представляется оправданным.

Обращаем внимание на инструкцию перехода на новую строку \n в тексто­вом аргументе метода println() в теле метода get() . Эта инструкция вклю­чена непосредственно в текст и ее наличие приводит к тому, что в месте размещения инструкции при выводе текста выполняется переход на новую строку. Поэтому в результате выполнения программы получим сообщение из двух строк:

Значения полей:

Re=1.0 и Im=5.0

Как уже отмечалось, это далеко не единственный способ использования ин­струкции this. Далее в книге есть и другие примеры.

 

Внутренние классы

 

Внутренний класс — это класс, объявленный внутри другого класса. Эту ситуа­цию не следует путать с использованием в качестве поля класса объекта другого класса. Здесь речь идет о том, что в рамках кода тела класса содержится описа­ние другого класса, который и называется внутренним. Класс, в котором объ­явлен внутренний класс, называется внешним. В принципе, внутренний класс может быть статическим, но такие классы используются на практике крайне редко, поэтому рассматривать мы их не будем, а ограничимся только нестатиче­скими внутренними классами.

Внутренний класс имеет несколько особенностей. Во-первых, члены внутрен­него класса доступны только в пределах внутреннего класса и недоступны во внешнем классе (даже если они открытые). Во-вторых, во внутреннем классе можно обращаться к членам внешнего класса напрямую. Наконец, объявлять внутренние классы можно в любом блоке внешнего класса. Пример использова­ния внутреннего класса приведен в листинге 4.6.

Листинг 4.6. Использование внутреннего класса

class MyOuter{

// Поле внешнего класса:

int number=123;

// Метод внешнего класса:

void show(){

// Создание объекта внутреннего класса:

MyInner InnerObj=new MyInner();

// Вызов метода объекта внутреннего класса:

InnerObj.display();}

// Внутренний класс:

class MyInner{

// Метод внутреннего класса: void display(){

System.out.println("Поле number="+number);}

}

}

class InnerDemo{

public static void main(String args[]){

// Создание объекта внешнего класса:

MyOuter OuterObj=new MyOuter();

// Вызов метода объекта внешнего класса:

OuterObj.show();}

}

В программе описаны три класса: внешний класс MyOuter, описанный в нем вну­тренний класс MyInner, а также класс InnerDemo. В классе InnerDemo описан метод main() , в котором создается объект внешнего класса MyOuter и вызывается метод этого класса show() .

Структура программы следующая: во внешнем классе MyOuter объявляется поле number, метод show() и описывается внутренний класс MyInner. У внутреннего класса есть метод display() , который вызывается из метода внешнего класса show() . Для вызова метода display() в методе show() создается объект внутрен­него класса InnerObj. Причина в том, что вызывать метод display() напрямую нельзя — члены внутреннего класса во внешнем классе недоступны.

В методе display() выводится сообщение со значением поля внешнего класса number. Поскольку во внутреннем классе допускается непосредственное обраще­ние к членам внешнего класса, обращение к полю number выполняется простым указанием его имени.

В результате выполнения программы получаем сообщение: Поле number=123

Отметим, что в главном методе программы можно создать объект внешнего класса, но нельзя создать объект внутреннего класса — за пределами внешнего класса внутренний класс недоступен.

Анонимные объекты

 

Как уже отмечалось, при создании объектов с помощью оператора new возвраща­ется ссылка на вновь созданный объект. Прелесть ситуации состоит в том, что эту ссылку не обязательно присваивать в качестве значения переменной. В таких слу­чаях создается анонимный объект. Другими словами, объект есть, а переменной, которая бы содержала ссылку на этот объект, нет. С практической точки зрения такая возможность представляется сомнительной, но это только на первый взгляд. На самом деле анонимные объекты требуются довольно часто — обычно в тех ситуациях, когда единожды используется единственный объект класса. Доста­точно простой пример применения анонимного объекта приведен в листинге 4.7.

 

Листинг 4.7. Анонимный объект

class MyClass{

void show(String msg){

System.out.println(msg);}

}

class NamelessDemo{

public static void main(String args[]){

// Использование анонимного объекта:

new MyClass().show("Этот объект не имеет имени");}

}

В классе MyClass описан всего один метод show() с текстовым аргументом. Тек­стовый аргумент — это объект встроенного Java-класса String. Действие метода состоит в том, что на экран выводится текст, переданный аргументом метода.

В методе main() класса NamelessDemo всего одна команда, которая и демонстриру­ет применение анонимного объекта:

new MyClass().show("Этот объект не имеет имени")

Эту команду можно условно разбить на две части. Инструкцией new MyClass() создается новый объект класса MyClass, а сама инструкция в качестве значения возвращает ссылку на созданный объект. Поскольку ссылка никакой перемен­ной в качестве значения не присваивается, созданный объект является аноним­ным. Однако это все равно объект класса MyClass, поэтому у него есть метод show() . Именно этот метод вызывается с аргументом "Этот объект не имеет имени". Для этого после инструкции new MyClass() ставится точка и имя метода с нуж­ным аргументом.

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

 








Дата добавления: 2016-06-13; просмотров: 1575;


Поиск по сайту:

При помощи поиска вы сможете найти нужную вам информацию.

Поделитесь с друзьями:

Если вам перенёс пользу информационный материал, или помог в учебе – поделитесь этим сайтом с друзьями и знакомыми.
helpiks.org - Хелпикс.Орг - 2014-2024 год. Материал сайта представляется для ознакомительного и учебного использования. | Поддержка
Генерация страницы за: 0.012 сек.