Главная » iPhone, Objective-C, Программирование для iOS и MacOS » Наш первый класс Objective-C

0

До сих пор мы использовали только готовые классы, созданные фирмой Apple. Пришло  время  заняться  написанием  собственных  классов.  Вспомните,  что  класс описывает две «стороны» объектов:

•  методы (экземпляров и класса), реализуемые классом;

•  переменные экземпляров, содержащиеся в каждом экземпляре класса.

Сейчас мы создадим класс Person, похожий на структуру Person, которую мы создали в главе 10. Класс будет определяться в двух файлах: Person.h и Person.m. Файл Person.h, называемый заголовочным или интерфейсным файлом, содержит объявления переменных и методов экземпляров. Файл Person.m называется файлом реализации. В нем программируются действия, необходимые для выполнения каждого метода.

Создайте новый проект: программу командной строки Foundation с именем

BMIТime.

Чтобы создать новый класс, выберите команду File→New→New File…. из раздела Маc OS Х на левой панели, выберите Сосоа и шаблон Objeсtive-C сlass. Присвойте классу имя Person и назначьте его субклассом NSObject. Наконец, убедитесь в том, что в окне выбрана цель BMIТime, и щелкните на кнопке Save.

Теперь в навигаторе проекта отображаются файлы нового класса, Person.h и Person.m. Откройте файл Person.h, включите в него объявления двух переменных экземпляров и трех методов экземпляров:

#import <Foundation/Foundation.h>

// класс Person наследует все переменные экземпляров

// и методы, определенные в классе NSObject

@interface Person : NSObject

{

// класс содержит две переменные экземпляров

float heightInMeters; int weightInKilos;

}

// методы, которые будут использоваться для присваивания

// значений переменных экземпляров

-­‐         (void)setHeightInMeters:(float)h;

-­‐        (void)setWeightInKilos:(int)w;

// метод для вычисления ИМТ

-­‐      (float)bodyMassIndex;

@end

Обратите внимание: переменные экземпляров объявляются в фигурных скобках, а методы – после переменных и вне фигурных скобок.

С точки зрения компилятора этот код говорит: «Я определяю новый класс с именем Person, и который входят все методы и переменные экземпляров класса NSObject. К ним я добавляю две переменные экземпляров: переменную типа float с именем heightInMeters и переменную типа int с именем weightInKilos. Также я собираюсь добавить три метода экземпляров, которые будут реализованы в Person.m».

Метод setHeightInMeters: получает аргумент типа float и не возвращает

значения, метод setWeightInKilos: получает аргумент тина int и не возвращает значения, а метод bodyMassIndex не получает аргументов и возвращает значение типа float.

Откройте файл Person.m. Удалите все существующие методы и реализуйте

методы, которые были объявлены:

#import "Person.h"

@implementation Person

-­‐         (void)setHeightInMeters:(float)h

{

heightInMeters = h;

}

-­‐        (void)setWeightInKilos:(int)w

{

weightInKilos = w;

}

-­‐      (float)bodyMassIndex

{

}

@end

return weightInKilos / (heightInMeters * heightInMeters);

Как видите, среда Xcode импортировала файл Person.h за вас. Также обратите

внимание на то, что имена реализованных методов должны в точности совпадать с именами, объявлеными в заголовочном файле. В Xcode это делается просто; когда вы начинаете вводить метод в файле реализации, Xcode предлагает выбрать одно из имен уже объявленых методов.

Итак,  все  методы,  объявленые  в  Person.h,  реализованы;  наш  класс  готов. Отредактируйте файл main.m, чтобы немного по экспериментировать с ним:

#import <Foundation/Foundation.h>

#import "Person.h"

int main(int argc, const char * argv[])

{

@autoreleasepool {

// создание экземпляра Person

Person *person = [[Person alloc] init];

// присваивание значение переменным экземпляра [person setWeightInKilos:96];

[person setHeightInMeters:1.8];

// вызов метода bodyMassIndex

float bmi = [person bodyMassIndex]; NSLog(@"person has a BMI of %f", bmi);

}

return 0;

}

Постройте и запустите программу. Файл Person.h импортируется для того, чтобы компилятор знал, какие методы были объявлены до их использования в main().

Рис. 17.1. Диаграмма объектов BMIТime

Методы доступа

Выполняя  это  же  упражнение  со  структурами  вместо  объектов,  мы  напрямую обращались к полям данных структуры из main ():

person.weightInKilos = 96;

person.heightInMeters = 1.8;

В объектно-ориентированных программах следует по возможности скрыть переменные экземпляров, чтобы они были известны и доступны только для самого объекта. А чтобы функции и методы за пределами Person могли задать значения веса и роста, мы создали методы setWeightlnKilos: и setHeightInMeters:. Такие методы называются sеt-методами (или методами записи).

Set-метод позволяет другим методам задать значение переменной экземпляра. Gеt-метод (метод чтения) позволяет другим методам прочитать значение переменной экземпляра. Set- и gеt- методы также называются методами доступа.

Добавьте в Person.h объявления get-методов:

#import <Foundation/Foundation.h>

@interface Person : NSObject

{

float heightInMeters; int weightInKilos;

}

// вы сможете задавать значения следующих переменных экземпляров

-­‐       (float)heightInMeters;

-­‐         (void)setHeightInMeters:(float)h;

-­‐      (int)weightInKilos;

-­‐        (void)setWeightInKilos:(int)w;

-­‐      (float)bodyMassIndex;

@end

Почему имена gеt-методов не включают префикс get по аналогии с именами sеt-методов? Потому что такое соглашение используется в Objective-C. Имя метода для чтения переменной экземпляра просто совпадает с именем этой переменной.

Теперь вернитесь к файлу Person.m и добавьте реализации gеt-методов:

@implementation Person

-­‐      (float)heightInMeters

{

return heightInMeters;

}

-­‐         (void)setHeightInMeters:(float)h

{

heightInMeters = h;

}

-­‐      (int)weightInKilos

{

return weightInKilos;

}

-­‐        (void)setWeightInKilos:(int)w

{

weightInKilos = w;

}

-­‐      (float)bodyMassIndex

{

}

@end

return weightInKilos / (heightInMeters * heightInMeters);

Остается использовать эти методы в main.m:

#import "Person.h"

int main(int argc, const char * argv[])

{

@autoreleasepool {

// создание экземпляра person

Person *person = [[Person alloc] init];

// присваивание значений переменным экземпляра [person setWeightInKilos:96];

[person setHeightInMeters:1.8];

// вызов метода bodyMassIndex

float bmi = [person bodyMassIndex]; NSLog(@"person (%d, %f) has a BMI of %f", [person weightInKilos], [person heightInMeters], bmi);

}

return 0;

}

Постройте и запустите программу.

Точечная запись

Программисты Objective-C часто используют методы доступа. Фирма Apple решила создать сокращенную запись для вызова методов доступа. Следующие две строки кода эквивалентны:

p = [x fido]; p = x.fido;

и эти две строки тоже работают одинаково:

[x setFido:3]; x.fido = 3;

Форма, в которой вместо квадратных скобок используется символ «точка»,

называется точечной записью.

Я стараюсь обходиться без использования точечной записи. Мне кажется, что она маскирует факт отправки сообщения и не соответствует соглашениям отправки всех остальных сообщений в системе. При желании вы можете использовать точечную завись в своих программах, но в этой книге она не встречается.

Свойства

Большая часть кода класса Person относится к методам доступа. Фирма Apple создала удобный механизм, упрощающий написание методов доступа, – так называемые свойства. При использовании свойств set- и get- методы можно объявлять в одной строке.

В  файле  Person.h  замените  объявление  set-  и  gеt-  методов  конструкцией

@property:

#import <Foundation/Foundation.h>

@interface Person : NSObject

{

float heightInMeters; int weightInKilos;

}

@property float heightInMeters;

@property int weightInKilos;

-­‐      (float)bodyMassIndex;

@end

Класс от этой правки не изменяется – просто вы используете более компактный синтаксис.

Теперь  загляните  в  файл  Person.m.  В  нем  полно  простых,  предсказуемых методов доступа. Если ваши методы доступа не делают ничего особенного, можно

просто  приказать  компилятору  синтезировать  методы  доступа  по  умолчанию  на основании объявления @property. Удалите методы доступа и замените их вызовом

@sупthеsizе:

#import "Person.h"

@implementation Person

@synthesize heightInMeters, weightInKilos;

-­‐      (float)bodyMassIndex

{

}

@end

return weightInKilos / (heightInMeters * heightInMeters);

Постройте и запустите программу. Все работает точно так же, как прежде, но

код стал куда более простым и удобным в сопровождении.

Источник: Аарон Хилегас, «Objective-C. Программирование для iOS и MacOS», 2012 г.

По теме:

  • Комментарии