Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Текст к презентации ООП на Java.doc
Скачиваний:
3
Добавлен:
01.03.2025
Размер:
206 Кб
Скачать
☆

Скрытие переменной экземпляра

Как известно, в Java недопустимо объявление двух локальных переменных с одним и тем же именем внутри той же самой, или включающей области действия идентификаторов. Заметим, что вы можете иметь локальные пере­менные, включая формальные параметры для методов, которые перекрыва­ются с именами экземплярных переменных класса. Однако, когда локальная переменная имеет такое же имя, как переменная экземпляра, локальная пе­ременная скрывает переменную экземпляра. Вот почему width, height и depth не использовались как имена параметров конструктора Box() внутри класса Box. Если бы они были использованы для именования этих парамет­ров, то, скажем width, как формальный параметр, скрыл бы переменную экземпляра width. Хотя обычно проще указывать различные имена, сущест­вует другой способ обойти эту ситуацию. Поскольку this позволяет обра­щаться прямо к объекту, это можно применять для разрешения любых кон­фликтов пространства имен, которые могли бы происходить между экземплярными и локальными переменными. Ниже представлена другая версия Box(), которая использует width, height и depth для имен параметров и за­тем применяет this, чтобы получить доступ к переменным экземпляра с те­ми же самыми именами:

// Используйте этот вариант конструктора

// для разрешения конфликтов пространства имен.

Box(double width, double height, double depth) {

this.width = width;

this.height = height;

this.depth = depth;

}

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

Передача аргументов

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

Когда методу передается простой тип, он передается по значению. Таким об­разом, то, что происходит с параметром, который принимает аргумент, ни­как не влияет на сам аргумент (т. е. аргумент при этом не изменяется). На­пример, рассмотрим следующую программу:

// Простые типы передаются по значению

class Test {

void meth(int i, int j) {

i *= 2; j /= 2;

}

}

class CallByValue {

public static void main(String args[]) {

Test ob = new Test();

int a = 15, b = 20;

System.out.println("а и b перед вызовом: "+a+" "+b);

ob.meth(a, b);

System.out.println("а и b после вызова: "+a+" "+b);

}

}

Когда вы передаете методу объект, ситуация изменяется, по­тому что объекты передаются по ссылке. При создании переменной типа "класс", создается только ссылка на объект. Таким обра­зом, когда вы передаете эту ссылку методу, принимающий ее параметр будет ссылаться на тот же самый объект, что и аргумент. Это и означает, что объ­екты передаются методам по ссылке. Все изменения объекта внутри метода затрагивают объект, используемый как аргумент. Например, рассмотрим следующую программу:

// Объекты передаются по ссылке.

class Test{

int a, b;

Test(int i, int j) {

a = i;

b = j;

}

// передать объект

void meth(Test o) {

o.a *= 2;

o.b /= 2;

}

}

class CallByRef {

public static void main(String args [] ) {

Test ob = new Test(15, 20);

System.out.println("ob.а и ob.b перед вызовом: " + ob.a + " " + ob.b);

ob.meth(ob);

System.out.println("ob.a и ob.b после вызова: " + ob.a + " " + ob.b);

}

}

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