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

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

Жанры

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

В этой строке сообщается, что AddressBook является объектом с родительским классом NSObject и подчиняется протоколу NSCopying. Поскольку система уже знает о методах, определенных ранее для этого протокола (в данном случае — из файла NSObject.h), эти методы не нужно объявлять в секции interface. Однако их нужно определить в вашей секции implementation.

В данном примере в секции implementation для AddressBook компилятор предполагает обнаружить определение метода copyWithZone:.

Если ваш класс принимает более одного протокола, просто перечислите их в угловых скобках, разделяя запятыми: @interface AddressBook: NSObject <NSCopying, NSCoding>

Здесь

компилятору сообщается, что класс AddressBook принимает протоколы NSCopying и NSCoding. В данном случае компилятор предполагает обнаружить определение всех требуемых методов (перечисленных в этих протоколах) в секции implementation для AddressBook.

Определив свой собственный протокол, вы не обязаны реализовать его сам и. Вы уведомляете других программистов, что если они хотят принять этот протокол, то должны реализовать соответствующие методы. Эти методы могут наследоваться из суперкласса. Так, если класс подчиняется протоколу NSCopying, это действительно и для его подклассов (хотя и не означает, что эти методы правильно реализованы для данного подкласса).

Протокол позволяет определить методы, которые будут реализовать другие люди, использующие подкласс нашего класса. Например, вы можете определить протокол Drawing для своего класса GraphicObjcct; п нем можно определить методы paint (окраска), erase (стирание) и outline (контур). @protocol Drawing -(void) paint; -(void) erase; @optional -(void) outline; @end

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

Примечание. Любые методы, которые указаны после директивы @optional директивы, не являются обязательными. Что человек, принявший протокол Drawing, не обязан реализовать метод outline, подчиняясь этому протоколу. (Вы можете вернуться к перечислению обязательных протоколов с помощью директивы @required в определении протокола.)

Таким образом, если вы создаете подкласс Rectangle класса GraphicObject и объявляете (то есть документируете), что ваш класс Rectangle подчиняется протоколу Drawing, пользователи данного класса будут знать, что они могут передавать экземплярам этого класса сообщения paint, erase и (возможно) outline.

Примечание. Это теория. Компилятор позволяет вам указать, что вы подчиняетесь протоколу, и выдает предупреждающие сообщения, только если вы не реализуете эти методы.

Отметим, что в протоколе нет ссылки ни на какие классы; это «бесклассовое» средство. Протоколу Drawing может подчиняться любой класс, не только подклассы GraphicObject.

Чтобы проверить, подчиняется ли объект какому-либо протоколу, можно использовать метод conformsToProtocol:. Например, вы хотите определить, подчиняется ли объект с именем currentObject протоколу Drawing, чтобы передавать этому объекту сообщения для рисования. Для этого можно написать следующее. id currentObject; ... if ([currentObject conformsToProtocol: @protocol (Drawing)] == YES) { // Передача сообщений currentObject paint, erase и/или outline ... }

Специальная директива @protocol, которая используется здесь, принимает имя протокола и создает объект типа Protocol, который используется как аргумент методом conformsToProtocol:.

Вы можете воспользоваться помощью компилятора,

чтобы проверить согласование с вашими переменными, заключив имя протокола в угловые скобки после имени типа: id <Drawing> currentObject;

Это указывает компилятору, что cunentObject будет содержать объекты, подчиняющиеся протоколу Drawing. Если присвоить currentObject объект статического типа, который не согласуется с протоколом Drawing (например, у вас есть несогласуюш ийся класс Square), то компилятор выдаст предупреждающее сообщение: warning: class 'Square' does not implement the 'Drawing' protocol (предупреждение: класс 'Square' не реализует протокол 'Drawing')

Здесь проверку выполняет компилятор, поэтому присваивание currentObject переменной типа id не приведет к выводу этого сообщения. Ддля объекта, хранящегося в переменной типа id, компилятор не сможет определить, подчиняется ли он протоколу Drawing.

В списке можно указать более одного протокола, если переменная будет содержать объект, подчиняющийся нескольким протоколам: id <NSCopying, NSCoding> myDocument;

Определение протокола можно расширить. В следующем объявлении протокола указывается, что протокол Drawing3D принимает также протокол Drawing. @protocol Drawing3D <Drawing>

Таким образом, класс, который принимает протокол Drawing3D, должен реализовать методы, перечисленные для этого протокола, а также методы из протокола Drawing.

И, наконец, категория тоже может принимать протокол, например: @interface Fraction (Stuff) <NSCopying, NSCoding>

Здесь Fraction содержит категорию Stuff, которая принимает протоколы NSCopying и NSCoding.

Как и имена классов, имена протоколов должны быть уникальными. Неформальные протоколы

В литературе встречается понятие неформального, свободного (informal) протокола. На самом деле это категория, содержащая список группы методов, но не реализующая их. Все (или почти все) наследуется из одного корневого объекта, поэтому неформальные категории часто определяются для корневого класса. Иногда неформальные протоколы называют также абстрактными (abstract) протоколами.

В header-файле могут встретиться объявления методов, которые выглядят следующим образом: @interface NSObject (NSComparisonMethods) -(BOOL)isEqualTo:(id)object; -(BOOL)isLessThanOrEqualTo:(id)object; -{B00L}isLessThan:(id)object; -<BOOL}isGreaterThanOrEqualTo:(id)object; BOOLJisGreaterThan: (id)object; -(BOOL)isNotEqualTo:(id)object; -{BOOL)doesContain:(id)object; -(B00L)isLike:(NSString *)object; -(BOOL)isCaselnsensitiveLike:(NSString *)object; @end

Здесь определяется категория с именем NSComparisonMethods для класса NSObject. В этом неформальном протоколе содержится список группы методов (в данном случае — девять), которые могут быть реализованы как часть этого протокола. Неформальный протокол — это фактически просто группа методов под определенным именем. Это полезно с точки зрения документирования и модульной организации методов.

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

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

Артефактор. Возвращение блудного императора

Седых Александр Иванович
2. Артефактор
Фантастика:
фэнтези
боевая фантастика
4.33
рейтинг книги
Артефактор. Возвращение блудного императора

Агенты ВКС

Вайс Александр
3. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
5.00
рейтинг книги
Агенты ВКС

Чужак

Листратов Валерий
1. Ушедший Род
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Чужак

Я спас СССР! том 1

Вязовский Алексей
1. Я спас СССР
Фантастика:
альтернативная история
6.57
рейтинг книги
Я спас СССР! том 1

Первый среди равных. Книга IX

Бор Жорж
9. Первый среди Равных
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Первый среди равных. Книга IX

Найденыш

Шмаков Алексей Семенович
2. Светлая Тьма
Фантастика:
юмористическое фэнтези
городское фэнтези
аниме
5.00
рейтинг книги
Найденыш

Последний Паладин. Том 8

Саваровский Роман
8. Путь Паладина
Фантастика:
боевая фантастика
попаданцы
5.00
рейтинг книги
Последний Паладин. Том 8

Я снова не князь! Книга XVII

Дрейк Сириус
17. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я снова не князь! Книга XVII

Разведчик. Заброшенный в 43-й

Корчевский Юрий Григорьевич
Героическая фантастика
Фантастика:
боевая фантастика
попаданцы
альтернативная история
5.93
рейтинг книги
Разведчик. Заброшенный в 43-й

Дважды одаренный. Том VII

Тарс Элиан
7. Дважды одаренный
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Дважды одаренный. Том VII

Юнлинг

Метельский Николай Александрович
Фантастика:
героическая фантастика
космическая фантастика
попаданцы
8.35
рейтинг книги
Юнлинг

Законы рода

Мельник Андрей
1. Граф Берестьев
Фантастика:
фэнтези
боевая фантастика
аниме
5.00
рейтинг книги
Законы рода

Бастард Императора. Том 10

Орлов Андрей Юрьевич
10. Бастард Императора
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Бастард Императора. Том 10

Группа крови на рукаве. Том 2

Вязовский Алексей
2. ГК
Фантастика:
боевая фантастика
альтернативная история
постапокалипсис
5.00
рейтинг книги
Группа крови на рукаве. Том 2