Вход/Регистрация
Программирование на 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.

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

  • Читать дальше
  • 1
  • ...
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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