Чтение онлайн

на главную - закладки

Жанры

Программирование на Objective-C 2.0
Шрифт:

Если объект принимает какой-либо формальный протокол, этот объект должен подчиняться всем требуемым сообщениям в этом протоколе. Это можно сделать как на этапе выполнения (runtime), так и во время компиляции. Если объект принимает неформальный протокол, то он не обязан принять все методы данного протокола (в зависимости от самого протокола). Подчинение неформальному протоколу можно сделать обязательным на этапе выполнения (с помощью respondsToSelector:), но не во время компиляции.

Примечание. Описанную выше директиву @optional (она была добавлена в Objective-C 2.0) можно использовать вместо неформальных протоколов. Она используется в нескольких классах UIKit (UIK.it — составная часть структур Cocoa Touch framework). 11.3.

Составные объекты

Вы уже знаете несколько способов, позволяющих расширить определение класса с помощью таких средств, как подклассы и категории. Еще один способ — это определение класса, который содержит один или несколько объектов из других классов. Объект из этого класса называется составным (composite) объектом, поскольку он составлен из других объектов.

В качестве примера рассмотрим класс Square (квадрат), который мы определили в главе 8. Он был определен как подкласс класса Rectangle (прямоугольник), поскольку квадрат это прямоугольник с равными сторонами. Подкласс, который мы определяем наследует все переменные экземпляра и методы родительского класса. В некоторых случаях это нежелательно. Метод setWidth:andHeight: (задание ширины и высоты) класса Rectangle наследуется классом Square, но реально не относится к квадрату (хотя действует правильно). Кроме того, создавая подкласс, мы должны обеспечить правильность работы наследуемых методов, поскольку пользователи этого подкласса будут иметь к ним доступ.

Вместо подкласса можно определить новый класс, который содержит в качестве одной из своих переменных экземпляра объект из класса, который вы хотите расширить. Затем нужно определить в новом классе только те методы, которые для него подходят. В примере с классом Square можно определить Square следующим образом. @interface Square: NSObject { Rectangle *rect; } -(int) setSide: (int) s; -(int) side; (сторона) •(int) area; (площадь) -(int) perimeter; (периметр) @end

Здесь определен класс Square с четырьмя методами. В отличие от версии с подклассом, которая дает непосредственный доступ к методам класса Rectangle (setWidth:, setHeight:, setWidthiandHeight:, width и height), этих методов нет в определении для Square. Это имеет смысл, поскольку не все методы подходят для работы с квадратами.

Если мы определяем класс Square таким способом, то он становится ответственным за выделение памяти для прямоугольника (rectangle), который содержит. Например, без заметающих методов оператор Square *mySquare = [[Square alloc] init];

выделяет память для нового объекта типа Square, но не выделяет память для объекта типа Rectangle, хранящегося в его переменной экземпляра red.

Чтобы выполнить выделение памяти, требуется замещение метода init или добавление нового метода, например, initWithSide:. Этот метод может выделять память для переменной Rectangle red и задавать соответствующим образом сторону (side). Необходимо также заместить метод dealloc (как описано для класса Rectangle в главе 8), чтобы освободить память, используемую для Rectangle red, когда освобождается сам объект Square.

Определяя свои методы в классе Square, мы по-прежнему можем использовать методы класса Rectangle. Например, мы можем реализовать метод area следующим образом: -(int) area { return [rect area]; }

Реализацию остальных методов вы можете написать в качестве упражнения (см. ниже упражнение 5). Упражнения

Выполните расширение категории MathOps из программы 11.1, чтобы дополнительно включить метод invert, который возвращает дробь (Fraction), обратную получателю.

Добавьте в класс Fraction категорию с именем Comparison. В этой категории добавьте два метода в соответствии со следующими объявлениями.
– (BOOL) isEqualTo: (Fraction *) 1; -(int) compare: (Fraction *) f; Первый метод должен возвращать значение YES, если две дроби равны, и значение N0 в противном случае. Правильно сравнивайте дроби (например, при сравнении дробей 3/4 и 6/8 следует возвращать значение YES). Второй метод должен возвращать

значение -1, если получатель меньше дроби, представляемой аргументом; возвращать 0, если две дроби равны; возвращать 1, если получатель больше дроби, представляемой аргументом.

Выполните расширение класса Fraction, добавив методы, которые подчиняются неформальному протоколу NSComparisonMethods, описанному з этой главе. Напишите реализацию первых шести методов из этого протокола (isEqualTo:, isLessThanOrEqualTo:, isLessThan:, isGreaterThanOrEquaHo:, isGreaterThan:,isNotEqualTo:) и выполните их тестирование.

Функции sin ,cos и tan {) включены в стандартную библиотеку Standard Library (как и scant ). Эти функции объявлены в header-файле , который вы должны импортировать в программу с помощью строки #import <math.h> Эти функции можно использовать для вычисления синуса, косинуса и тангенса аргумента типа double, выраженного в радианах. Возвращаемый результат является значением с плавающей точкой двойной точности. Например, для вычисления синуса аргумента d, где d — угол, выраженный в радианах, можно использовать следующую строку: result = sin (d); Добавьте категорию с именем Trig в класс Calculator, определенный в главе 6. Включите в эту категорию методы для вычисления синуса, косинуса и тангенса в соответствии со следующими объявлениями.
– (double) sin; -(double) cos; -(double) tan;

Напишите секцию implementation для Square и выполните тестирование программы для проверки ее методов, используя описание составных объектов из этой главы и следующую секцию interface, @interface Square: NSObject { Rectangle *rect; } -(Square*) initWithSide: (int) s; -(void) setSide: (int) s; -(int) side; -(int) area; -(int) perimeter; -(void) dealloc; // Замещающий метод для освобождения памяти объекта типа Rectangle @end

Глава 12. Препроцессор

Препроцессор содержит средства, упрощающие чтение, разработку и встраивание программ в различные системы. Препроцессор позволяет настроить язык Objective-C в соответствии с конкретным программным приложением или вашим стилем программирования.

Препроцессор — это составная часть процесса компиляции Objective-C. Он распознает специальные операторы и обрабатывает их, прежде чем будет выполнен анализ самой программы. Операторы препроцессора идентифицируются знаком «решетка» (#), который должен быть первым символом строки, отличным от пробела. Синтаксис операторов препроцессора несколько отличаюется от обычных операторов Objective-C. Мы начнем с описания оператора #define. 12.1. Оператор # define

Оператор #define позволяет присваивать символические имена программным константам. Оператор препроцессора #define TRUE 1

определяет имя TRUE и делает его эквивалентным значению 1. Затем имя TRUE можно использовать в любом месте программы, где могла бы использоваться константа 1. Там, где появляется это имя, препроцессор автоматически подставляет вместо него значение 1. Например, следующий оператор Objective-C использует определенное имя TRUE. gameOver = TRUE;

Этот оператор присваивает значение TRUE переменной gameOver. Вам не обязательно помнить, какое конкретное значение вы определили для TRUE. Приведенный выше оператор будет присваивать 1 переменной gameOver. Оператор препроцессора #define FALSE О

определяет имя FALSE и делает его эквивалентным значению 0. Например, оператор gameOver = FALSE;

присваивает значение FALSE переменной gameOver, а оператор if ( gameOver == FALSE)

сравнивает значение gameOver с определенным значением FALSE.

Определенное таким образом имя не является переменной, поэтому вы не можете присвоить ему значение, если результатом подстановки значения не янляется переменная. Если в программе используется определенное имя, препроцессор автоматически подставляет то, что представлено в правой части оператора «define. Это аналогично операции поиска и замены втекстозом редакторе; в данном случае препроцессор заменяет все экземпляры определенного имени соответствующим текстом.

Поделиться:
Популярные книги

На границе империй. Том 4

INDIGO
4. Фортуна дама переменчивая
Фантастика:
космическая фантастика
6.00
рейтинг книги
На границе империй. Том 4

Антимаг его величества. Том III

Петров Максим Николаевич
3. Модификант
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Антимаг его величества. Том III

Ст. сержант. Назад в СССР. Книга 5

Гаусс Максим
5. Второй шанс
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Ст. сержант. Назад в СССР. Книга 5

Черный Маг Императора 18

Герда Александр
18. Черный маг императора
Фантастика:
юмористическое фэнтези
аниме
сказочная фантастика
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Черный Маг Императора 18

Последний наследник

Тарс Элиан
11. Десять Принцев Российской Империи
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Последний наследник

Здравствуй, 1985-й

Иванов Дмитрий
2. Девяностые
Фантастика:
альтернативная история
5.25
рейтинг книги
Здравствуй, 1985-й

Лейтенант. Назад в СССР. Книга 8. Часть 1

Гаусс Максим
8. Второй шанс
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Лейтенант. Назад в СССР. Книга 8. Часть 1

Кай из рода красных драконов

Бэд Кристиан
1. Красная кость
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Кай из рода красных драконов

На границе империй. Том 8. Часть 2

INDIGO
13. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 8. Часть 2

Я - злодейка в дораме. Сезон второй

Вострова Екатерина
2. Выжить в дораме
Фантастика:
уся
фэнтези
сянься
попаданцы
5.00
рейтинг книги
Я - злодейка в дораме. Сезон второй

Последний рейд

Сай Ярослав
5. Медорфенов
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Последний рейд

Хозяин Теней

Петров Максим Николаевич
1. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Хозяин Теней

Черный Маг Императора 6

Герда Александр
6. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
7.00
рейтинг книги
Черный Маг Императора 6

Ермак. Противостояние. Книга одиннадцатая

Валериев Игорь
11. Ермак
Фантастика:
попаданцы
альтернативная история
4.50
рейтинг книги
Ермак. Противостояние. Книга одиннадцатая