АБОБА. Справочник по программированию на Java Методическое пособие
Скачать 242.41 Kb.
|
Присваивание переменных объектных ссылокПри выполнении присваивания переменные объектных ссылок действуют иначе, чем можно было бы представить. Например, какие действия, по вашему мнению, выполняет следующий фрагмент? Box b1 = new Box(); Box b2 = b1; Можно подумать, что переменной b2 присваивается ссылка на копию объекта, на которую ссылается переменная b1. То есть может показаться, что b1 и b2 ссылаются на отдельные и различные объекты. Однако это не так. После выполнения этого фрагмента кода обе переменные b1 и b2 будут ссылаться на один и тот же объект. Присваивание b1 переменной b2 не привело к распределению какой-то памяти или копированию какойлибо части исходного объекта. Эта операция присваивания приводит лишь к тому, что переменная b2 ссылается на тот же объект, что и переменная b1. Таким образом, любые изменения, выполненные в объекте через переменную b2, окажут влияние на объект, на который ссылается переменная b1, поскольку это – один и тот же объект. Хотя и b1 и b2 ссылаются на один и тот же объект, эти переменные не связаны между собой никаким другим образом. Например, следующая операция присваивания значения переменной b1 просто разорвет связь переменной b1 с исходным объектом, не оказывая влияния на сам объект или на переменную b2: Box b1 = new Box(); Box b2 = b1; // ... b1 = null; В этом примере значение b1 установлено равным null, но переменная b2 по-прежнему указывает на исходный объект. Присваивание ссылочной переменной одного объекта ссылочной переменной другого объекта не ведет к созданию копии объекта, а лишь создает копию ссылки. Знакомство с методамиКак было сказано в начале этой главы, обычно классы состоят из двух элементов: переменных экземпляра и методов. Поскольку язык Java предоставляет им столь большие возможности и гибкость, тема методов очень обширна. Фактически многие последующие главы посвящены методам. Однако чтобы можно было приступить к добавлению методов к своим классам, необходимо ознакомиться с рядом их основных характеристик. Общая форма объявления метода выглядит следующим образом: тип имя(список_параметров) { // тело метода } Здесь тип указывает тип данных, возвращаемых методом. Он может быть любым допустимым типом, в том числе типом класса, созданным программистом. Если метод не возвращает значение, типом его возвращаемого значения должен быть void. Имя служит для указания имени метода. Оно может быть любым допустимым идентификатором, кроме тех, которые уже используются другими элементами в текущей области определения. Список_параметров – последовательность пар “тип-идентификатор”, разделенных запятыми. По сути, параметры – это переменные, которые принимают значения аргументов, переданных методу во время его вызова. Если метод не имеет параметров, список параметров будет пустым. Методы, тип возвращаемого значения которых отличается от void, возвращают значение вызывающей процедуре с помощью следующей формы оператора return: return значение; Здесь значение – это возвращаемое значение. Хотя было бы весьма удобно создать класс, который содержит только данные, в реальных программах подобное встречается редко. В большинстве случаев для осуществления доступа к переменным экземпляра, определенным классом, придется использовать методы. Фактически методы определяют интерфейсы большинства классов. Это позволяет программисту, который реализует класс, скрывать конкретную схему внутренних структур данных за более понятными абстракциями метода. Кроме определения методов, которые обеспечивают доступ к данным, можно определять также методы, используемые внутренне самим классом. // Эта программа содержит метод внутри класса box. class Box { double width; double height; double depth; // отображение объема параллелепипеда void volume() { System.out.print("Объем равен "); System.out.println(width * height * depth); } } class BoxDemo3 { public static void main(String args[]) { Box mybox1 = new Box(); Box mybox2 = new Box(); // присваивание значений переменным экземпляра mybox1 mybox1.width = 10; mybox1.height = 20; mybox1.depth = 15; /* присваивание других значений переменным экземпляра mybox2 */ mybox2.width = 3; mybox2.height = 6; mybox2.depth = 9; // отображение объема первого параллелепипеда mybox1.volume(); // отображение объема второго параллелепипеда mybox2.volume(); } } Эта программа генерирует следующий вывод, совпадающий с выводом предыдущей версии: Объем равен 3000.0 Объем равен 162.0 Внимательно взгляните на следующие две строки кода: mybox1.volume(); mybox2.volume(); В первой строке присутствует обращение к методу volume(), определенному в mybox1. То есть она вызывает метод volume() по отношению к объекту mybox1, для чего было использовано имя объекта, за которым следует символ операции точки. Таким образом, обращение к mybox1.volume() отображает объем параллелепипеда, определенного объектом mybox1, а обращение к mybox2.volume() – объем параллелепипеда, определенного объектом mybox2. При каждом вызове метода volume() он отображает объем указанного параллелепипеда. Соображения, приведенные в следующих абзацах, облегчат понимание концепции вызова метода. При вызове метода mybox1.volume() система времени выполнения Java передает управление коду, определенному внутри метода volume(). По завершении выполнения всех операторов внутри метода управление возвращается вызывающей программе и ее выполнение продолжается со строки, которая следует за вызовом метода. В самом общем смысле можно сказать, что метод – способ реализации подпрограмм в Java. В методе volume() следует обратить внимание на один очень важный нюанс: ссылка на переменные экземпляра width, height и depth выполняется непосредственно, без указания перед ними имени объекта или операции точки. Когда метод использует переменную экземпляра, которая определена его классом, он выполняет это непосредственно, без указания явной ссылки на объект и без применения операции точки. Это становится понятным, если немного подумать. Метод всегда вызывается по отношению к какому-то объекту его класса. Как только этот вызов выполнен, объект известен. Таким образом, внутри метода вторичное указание объекта совершенно излишне. Это означает, что width, height и depth неявно ссылаются на копии этих переменных, хранящиеся в объекте, который вызывает метод volume(). |