Вход/Регистрация
Программирование на Objective-C 2.0
вернуться

Кочан Стивен

Шрифт:

Используя определения float f = 1.00; short int i = 100; long int I = 500L; double d = 15.00; и семь шагов, описанных выше для преобразования операндов в выражениях, определите тип и значение следующих выражений. f + i l/d i / l + f 1 * i f / 2 i / (d + f) 1 / (i * 2.0) I + i / (double) I

Напишите программу, которая определяет, выполняется ли на вашей машине расширение для знака у переменных signed char.

Глава 11. Категории и протоколы

В этой главе описывается, как добавлять методы для класса в модульном стиле с помощью категорий и как создавать стандартизованный список методов для реализации другими людьми. 11.1. Категории

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

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

Вы изучили, как использовать класс массивов из библиотеки Foundation framework с именем NSArray и поняли, что в этом классе необходимо реализовать один или нескольких методов. Конечно, вы могли бы написать новый подкласс класса NSArray и реализовать эти новые методы, но есть более простой способ. На практике для разрешения подобных ситуаций используются категории (category). Категория представляет простой способ модульного определения класса в виде групп или категорий связанных методов. Она также позволяет достаточно просто расширить существующее определение класса без доступа к существующему исходному коду этого класса или создания подкласса. Это мощная и достаточно простая для изучения концепция.

Вернемся к первому примеру и покажем, как добавить новую категорию в класс Fraction для работы с четырьмя основными арифметическими операциями. Приведем исходную секцию interface для Fraction. #import <Foundation/Foundation.h> #import <stdio.h> // Определение класса Fraction @interface Fraction : NSObject { int numerator; int denominator; } @property int numerator, denominator; -(void) setTo: (int) n over: (int) d; -(Fraction *) add: (Fraction *) f; -(void) reduce; -(double) convertToNum; -(void) print; @end

Теперь удалим метод add: из этой секции interface и добавим его в новую категорию вместе с тремя другими арифметическими операциями, которые нужно реализовать. Ниже показана секция in te rfa c e д л я новой категории MathOpS. #import «Fraction.h» @interface Fraction (MathOps) -(Fraction *) add: (Fraction *) f; -(Fraction *) mul: (Fraction *) f; -(Fraction *) sub: (Fraction *) f; -(Fraction *) div: (Fraction *) f; @end

Здесь представлено некоторое определение секции interface, по на самом деле это расширение существующей секции. Мы должны включить исходную секцию interface, чтобы указать компилятору на класс Fraction (правда, вы можете включить эту новую категорию непосредственно в исходный файл Fraction.h).

После строки «import мы вилим следующую строку: @interface Fraction (MathOps)

Она указывает компилятору, что для класса Fraction определяется новая категория с именем MathOps. Имя категории после имени класса заключено в круглые скобки. Отметим, что здесь не указывается родительский класс для Fraction; компилятору уже извес тно о нем из Fraction.h. Кроме того, мы ничего не сообщаем ему о переменных экземпляра, хотя делали это во всех предыдущих секциях interface. На самом деле мы получим от компилятора сообщение о синтаксической ошибке, если попытаемся включить родительский класс или переменные экземпляра.

Эта секция interface указы вает компилятору, что мы добавляем в класс Fraction расширение под категорией с именем MathOps. Категория MathOps содержит четыре метода экземпляра: add:, mul:, sub: и div:. Каждый метод получает в качестве аргумента дробь (fraction) и возвращает тоже дробь.

Определения всех этих четырех методов можно поместить в одну секцию implementation.Мы можем определить в одной секции implementation все методы из секции interface файла Fraction.h плюс методы из категории MathOps. Мы также можем определить методы из этой категории в отдельной секции implementation. Тогда в секции implementation для этих методов следует также идентифицировать категорию, к которой принадлежат эти методы. Как и в секции interface, имя категории после имени класса нужно заключить: в круглые скобки @implementation Fraction (MathOps) // код для методов этой категории ... @end

В программе 11.1 для новой категории MathOps секции interface и implementation объединены в одном файле вместе с тестовой процедурой. #import "Fraction.h" @interface Fraction (MathOps) -(Fraction *) add: (Fraction *) f; -(Fraction *) mul: (Fraction *) f; -(Fraction *) sub: (Fraction *) f; -(Fraction *) div: (Fraction *) f; @end @implementation Fraction (MathOps) -(Fraction *) add: (Fraction *) f { // Для сложения двух дробей: // a/b + c/d = ((a*d) + (b*c)) / (b * d) Fraction *result = [[Fraction alloc] init]; int resultNum, resultDenom; resultNum = (numerator * f.denominator) + (denominator * f.numerator); resultDenom = denominator * f.denominator; [result setTo: resultNum over: resultDenom]; [result reduce]; return result; } -(Fraction *) sub: (Fraction *) f // Для вычитания двух дробей: // a/b - c/d = ((a*d) - (b*c)) / (b * d) Fraction *result = [[Fraction alloc] init]; int resultNum, resultDenom; resuUNum = (numerator * f.denominator) - (denominator * {.numerator); resultDenom = denominator * f.denominator; [result setTo: resultNum over: resultDenom]; [result reduce]; return result; } -(Fraction *) mul: (Fraction *) f { Fraction *result = [[Fraction alloc] init]; [result setTo: numerator * f.numerator over: denominator * f.denominator]; [result reduce]; return result; } -(Fraction *) div: (Fraction *) f { Fraction *result = [[Fraction alloc] init]; [result setTo: numerator * f.denominator over: denominator * {.numerator]; [result reduce]; return result; } @end int main (int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; Fraction *a = [[Fraction alloc] init]; Fraction *b = [[Fraction alloc] init]; Fraction *result; [a setTo: 1 over: 3]; [b setTo: 2 over: 5]; [a print]; NSLog (@" +"); [b print]; NSLog (@"----"); result = [a add: b]; [result print]; NSLog (@ "\n"); [result release]; [а print]; NSLog (@" -"); [b print]; NSLog (@"----"); result = [a sub: b]; [result print]; NSLog (@"\n"); [result release]; [a print]; NSLog (@" *"); [b print]; NSLog (@"----"); result = [a mul: b]; [result print]; NSLog (@"\n"); [result release]; [a print]; NSLog (@" /"); [b print]; NSLog (@"----"); result = [a div: b]; [result print]; NSLog (@"\n"); [result release]; [a release]; [b release]; [pool drain]; return 0; }

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

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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