Программирование на Objective-C 2.0
Шрифт:
Метод экземпляра выполняет определенную операцию для определенного экземпляра класса, например, задает его значение, читает его значение, выводит на экран его значение и т.д. Возвращаемые значения
При объявлении нового метода вы должны сообщить компилятору Objective- С, будет ли метод возвращать значение, и если да, то указать тип возвращаемого значения. Для этого нужно заключить тип возвращаемого значения в круглые скобки после ведущего символа «минус» или «плюс». Приведенное ниже объявление указывает, что метод экземпляра с именем retrieveNumerator возвращает целое значение. -(int) retrieveNumerator;
В следующей строке объявляется метод, который возвращает значение с двойной точностью. (Подробнее
Значение возвращается из метода с помощью оператора Objective-C return аналогично значению, возвращаемому из main в примерах предыдущей програм-мы. Если метод не возвращает никакого значения, нужно указать это с помощью типа void, как в следующем примере: -(void) print;
Это объявление метода экземпляра print, этот метод не возвращает никакого значения. В подобных случаях вам не нужно выполнять оператор return в конце метода. Можно выполнить return без указания какого-либо значения: return;
Указывать тип возвращаемого значения для методов необязательно, хотя практика программирования рекомендует это делать. Если тип не указан, то по умолчанию используется тип id. Подробнее о типе данных id см. в главе 9. По сути, тип id можно использовать для ссылки на любой тип объекта. Аргументы для метода
В секции @interface программы 3.2 объявляется еще два метода. -(void) setNumerator: (int) n; -(void) setDenominator: (int) d;
Оба метода экземпляра не возвращают никакого значения. Каждому методу передается целый аргумент (параметр), который указывается типом (int) перед именем аргумента. В случае setNumerator имя аргумента — п. Это имя выбирается произвольно и используется методом для ссылки на аргумент. В объявлении setNumerator устанавливается, что один целый аргумент с именем п будет пере-даваться методу, а метод не будет возвращать значение. Метод setDenominator лей- ствует так же, но его аргумент имеет имя d.
Обратите внимание на синтаксис объявления методов. Имя каждого метода заканчивается двоеточием, указывая компилятору Objective-C, что для метода должен быть указан аргумент. Затем указывается тип аргумента, заключенный в круглые скобки. Так же указывается тип возвращаемого значения для самого метода. И, наконец, символическое имя указывает, что для метода задан аргу-мент. В конце объявления ставится точка с запятой. Этот синтаксис показан на рис. 3.1.
Рис. 3.1. Объявление метода
Если методу передается аргумент, то при ссылке на этот метод нужно доба-вить двоеточие после имени метода. В нашем случае необходимо указать setNumerator: и setDenominator:. Ссылка на метод print без двоеточия в конце имени указывает, что этому методу не передаются аргументы. В главе 7 рассмативают- ся методы, которым передается несколько аргументов. 3.5. Секция @implementation
Как говорилось выше, секция @implementation содержит код для методов, объяв-ленных в секции @interface. В секции @implementation вы объявляете (declare) ме-тоды в секции @interface и определяете их (define), то есть пишете для них конк-ретный код.
В общем виде секция @implementation имеет следующий формат. @implementation Имя-Нового-Класса Определения-методов; @end
Имя-Нового-Класса — то же самое имя, которое использовалось для данного класса в секции @interface. Можно использовать двоеточие в конце имени и затем имя родительского класса, как мы делали в секции @interface: @implementation Fraction: NSObject
Однако это не обязательно, и обычно не делается.
Часть Определения-методов секции @implementation содержит код для каждого метода, указанного в секции @interface. Аналогично секции @interface, определение каждого метода начинается с
указания типа метода (для класса или экземпляра), типа возвращаемого значения, аргументов метода и их типов. Но вместо завершения строки символом «точка с запятой» следует код для этого метода, заключенный в фигурные скобки.Рассмотрим секцию @implementation из программы 3.2. //---- @implementation section ---- @implementation Fraction -(void) print { NSLog ("%i/%i", numerator, denominator); } -(void) setNumerator: (int) n { numerator = n; ) -(void) setDenominator: (int) d { denominator = d; } @end
В методе print используется NSLog для вывода значений переменных экземпляра numerator и denominator, numerator и denominator — это переменные экземпляра в объекте, который является получателем сообщения. Это важная концепция, и мы еще вернемся к ней.
Метод setNumerator: сохраняет значение целого аргумента, которому мы при-своили имя п, в переменной экземпляра numerator. Метод setDenominator: сохраняет значение аргумента d в переменной экземпляра denominator. 3.6. Секция program
Секция program содержит код для решения конкретной задачи, которая может включать много файлов. Как говорилось выше, наличие процедуры main является обязательным. В ней начинается выполнение программы. Ниже приводится секция program из программы 3.2. //—- program section —- int main (int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; Fraction *myFraction; // Create an instance of a Fraction (Создание экземпляра класса Fraction) myFraction = [Fraction alloc]; myFraction = [myFraction init]; // Set fraction to 1/3 (Задание значения дроби 1/3) [myFraction setNumerator: 1]; [myFraction setDenominator: 3]; // Display the fraction using the print method (Вывод дроби с помощью метода print) NSLog (@The value of myFraction is:"); [myFraction print]; [myFraction release]; [pool drain]; return 0; }
Внутри процедуры main вы определяете переменную с именем myFraction: Fraction *myFraction;
Здесь указывается, что myFraction является объектом типа Fraction, то есть myFraction используется для хранения значений из вашего нового класса Fraction. Звездочка (*) перед myFraction является обязательным элементом. Технически она обозначает, что myFraction является на самом деле ссылкой (или указателем — pointer) на Fraction. Мы рассмотрим ссылки позднее.
Теперь, когда у нас имеется объект для хранения дроби (Fraction), нужно создать саму дробь. myFraction = [Fraction alloc];
alloc — это сокращение от allocate (выделить). Вам нужно выделить пространство в памяти для новой дроби. С помощью этого выражения происходит отправка сообщения новому классу Fraction: [Fraction alloc]
Вы обращаетесь к классу Fraction для применения метода alloc, но вы не опре-деляли метод alloc. Он был унаследован из родительского класса. Эта тема рас-сматривается в главе 8.
Отправив классу сообщение alloc, вы получаете в ответ новый экземпляр этого класса. В программе 3.2 возвращаемое значение сохраняется внутри переменной myFraction. Метод alloc очищает все переменные экземпляра объекта. Затем вам нужно инициализировать объект после выделения памяти для него.
Это выполняет оператор: myFraction = [myFraction init];
Здесь используется метод init, который инициализирует экземпляр класса. Сообщение init отправляется в myFraction. Вам нужно инициализировать конк-ретный объект Fraction, поэтому вы отправляете сообщение не классу, а экземп-ляру этого класса.
Метод init возвращает также значение — инициализированный объект. Это возвращаемое значение сохраняется в переменной myFraction. Эта последовательность из двух строк (выделение памяти для нового экземпляра класса и последующая его инициализация) выполняется в Objective-C так часто, что два сообщения обычно объединяются: myFraction = [[Fraction alloc] init];