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

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

Жанры

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

Но вы должны сделать так, чтобы память, выделенная для предыдущего начала (origin), была освобождена до того, как будет задано новое начало. Это можно сделать в методе setOrigin:. -(void) setOrigin: (XYPoint *) pt { if (origin) [origin release]; origin = [[XYPoint alloc] init]; [origin setX: pt.x andY: pt.y]; }

Если вы синтезируете свои методы доступа, то можете сделать так, чтобы компилятор автоматически разрешил эту проблему. 8.4. Расширение через наследование: добавление новых переменных экземпляра

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

Вернемся к простым классам ClassA и ClassB и внесем некоторые изменения. Добавим в ClassB новую переменную экземпляра у. @interface ClassB: ClassA { int у; } -(void) printVar; @end

Может показаться, что ClassB будет иметь только одну переменную экземпляра (с именем у), но, исходя из предыдущего объявления, на самом деле он имеет две. Он имеет его собственную переменную экземпляра у и наследует переменную х из класса ClassA.

Примечание. Этот класс имеет также переменные экземпляра, которые наследует из класса NSObject, но мы пока будет игнорировать этот факт. Ниже приводится простой пример этой концепции (программа 8.8). // Расширение переменных экземпляра #import <Foundation/Foundation.h> // Объявление и определение ClassA @interface ClassA: NSObject { int x; } -(void) initVar; @end @implementation ClassA -(void) initVar { x = 100; } @end // Объявление и определение ClassB @interface ClassB: ClassA { int у; } -(void) initVar; -(void) printVar; @end @implementation ClassB -(void) initVar x = 200; у = 300; ) -(void) printVar { NSLog (@"x = %i", x); NSLog (@"y = %i", y); } @end int main (int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; ClassB *b = [[ClassB alloc] init]; [b initVar]; // uses overriding method in ClassB [b printVar]; // reveal values of x and y; [b release]; [pool drain]; return 0; }

Вывод программы 8.8 x = 200 у = 300

Объект b класса ClassB инициализируется путем вызова метода initVar, определенного в классе ClassB. Этот метод замещает метод initVar из ClassA, присваивает значение 200 переменной х (унаследованное из ClassA) и значение 300 — переменной у (определенной в ClassB). Метод printVar выводит значения этих переменных экземпляра.

Есть много других тонкостей, связанных с выбором метода в ответ на сообщение, особенно в тех случаях, когда получателем является один из нескольких классов. Это динамическое связывание (dynamic binding), которое рассматривается в следующей главе. 8.5. Абстрактные классы

Мы закончим эту главу, добавив еще немного терминологии, связанной с понятием наследования.

Иногда классы создаются просто для того, чтобы упростить другим создание подкласса. Такие классы называют абстрактными (abstract) или абстрактными суперклассами. В этом классе определяются методы и переменные экземпляра, но при этом не предполагается, что кто-либо будет создавать экземпляры из этого класса. Например, р нет никакого смысла определить объект непосредственно из корневого объекта NSObject. Foundation framework (см. часть II) содержит несколько абстрактных классов. Например, класс Foundation NSNumber является абстрактным классом, который был создан для работы с числами как с объектами. Для хранения целых чисел и чисел с плавающей точкой обычно требуются разные размеры памяти. Для каждого числового типа существуют отдельные подклассы NSNumber. Поскольку эти подклассы, в отличие от их абстрактных суперклассов, реально существуют, их называют конкретными (concrete) подклассами. Каждый конкретный подкласс является дочерним классом класса NSNumber и называется кластером (cluster). Когда вы отправляете сообщение классу NSNumber для создания нового объекта типа integer, используется соответствующий подкласс, чтобы выделить память для этого объекта и задать его значение. Эти подклассы на самом деле являются частными. Вы не можете выполнить непосредственный доступ к этим подклассам сами; доступ осуществляется косвенно через абстрактный суперкласс. Абстрактный суперкласс представляет общий интерфейс для работы со всеми типами числовых объектов и позволяет вам не знать, какой тип числа вы сохранили в вашем числовом объекте и как задавать и считывать его значение. Упражнения

Добавьте в программе 8.1 новый класс с именем ClassC, который является подклассом класса ClassB. Создайте метод initVar, который присваивает значение 300 своей переменной экземпляра х. Напишите тестовую процедуру, которая объявляет объекты классов ClassA, ClassB и ClassC и вызывает их методы initVar.

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

Внесите изменения в программу 8.1, чтобы добавить новый класс с именем ClassB2, который, как и ClassB, является подклассом класса ClassA. Что вы можете сказать о связи между ClassB и ClassB2? Укажите иерархические связи между классом NSObject, классом ClassA, ClassB и ClassB2. Что является суперклассом для ClassB? Что является суперклассом для ClassB2? Сколько подклассов может иметь класс, и сколько он может иметь суперклассов?

Напишите метод Rectangle с именем translate:, который принимает в качестве своего аргумента вектор с именем XYPoint (xv,yv). Сделайте так, чтобы он смещал начало прямоугольника (origin) на указанный вектор.

Определите новый класс с именем GraphicObject и сделайте его подклассом NSObject. Определите переменные экземпляра в этом новом классе следующим образом. int fillColor; // 32-битный цвет BOOL filled; // Заполняется ли объект? int lineColor; // 32-битный цвет линии

Напишите методы, которые задают и считывают значения определенных выше переменных.

Сделайте класс Rectangle подклассом GraphicObject. Определите новые классы Circle (Круг) и Triangle (Треугольник), которые тоже являются подклассами GraphicObject. Напишите методы, чтобы задавать и считывать параметры для этих объектов, вычислять длину окружности и площадь круга, периметр и площадь треугольника.

Напишите метод для Rectangle с именем intersect:, который принимает прямоугольник как аргумент и возвращает прямоугольник, представляющий площадь перекрытия этих прямоугольников. Например, для двух прямоугольников, показанных на рис. 8.Ю, метод должен возвращать прямоугольник, начало (origin) которого находится в точке (400, 420), ширина (width) равна 50 и высота (height) равна 60.

Рис. 8.10. Пересечение прямоугольников

Если прямоугольники не пересекаются, нужно возвратить прямоугольник с шириной и высотой 0 и началом (0,0).

Напишите метод для класса Rectangle с именем draw, который рисует прямоугольник из знаков «минус» и «вертикальная черта». Следующая последовательность кодов Rectangle *myRect = [[Rectangle alloc] init]; [myRect setWidth: 10 and Height: 3]; [myRect draw]; [myRect release]; _______ | | | | | | _______

Глава 9. Полиморфизм, динамический контроль типов и динамическое связывание

В этой главе описываются возможности языка Objective-C, которые делают его столь мощным языком программирования и отличают его от некоторых объектно-ориентированных языков, таких как C++. Это три ключевых концепции: полиморфизм, динамический контроль типов и динамическое связывание.

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

Воин

Бубела Олег Николаевич
2. Совсем не герой
Фантастика:
фэнтези
попаданцы
9.25
рейтинг книги
Воин

Я еще барон. Книга III

Дрейк Сириус
3. Дорогой барон!
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Я еще барон. Книга III

Аристократ из прошлого тысячелетия

Еслер Андрей
3. Соприкосновение миров
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Аристократ из прошлого тысячелетия

Личный аптекарь императора. Том 3

Карелин Сергей Витальевич
3. Личный аптекарь императора
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Личный аптекарь императора. Том 3

Наследие Маозари 3

Панежин Евгений
3. Наследие Маозари
Фантастика:
рпг
аниме
5.00
рейтинг книги
Наследие Маозари 3

Третий

INDIGO
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
Третий

Граф

Ланцов Михаил Алексеевич
6. Помещик
Фантастика:
альтернативная история
5.00
рейтинг книги
Граф

Изгой Проклятого Клана

Пламенев Владимир
1. Изгой
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Изгой Проклятого Клана

Идеальный мир для Лекаря 22

Сапфир Олег
22. Лекарь
Фантастика:
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Идеальный мир для Лекаря 22

Магнатъ

Кулаков Алексей Иванович
4. Александр Агренев
Приключения:
исторические приключения
8.83
рейтинг книги
Магнатъ

Родословная. Том 1

Ткачев Андрей Юрьевич
1. Линия крови
Фантастика:
городское фэнтези
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Родословная. Том 1

Как я строил магическую империю 4

Зубов Константин
4. Как я строил магическую империю
Фантастика:
боевая фантастика
постапокалипсис
аниме
фантастика: прочее
фэнтези
5.00
рейтинг книги
Как я строил магическую империю 4

Виктор Глухов агент Ада. Компиляция. Книги 1-15

Сухинин Владимир Александрович
Виктор Глухов агент Ада
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
попаданцы
5.00
рейтинг книги
Виктор Глухов агент Ада. Компиляция. Книги 1-15

Закрытые Миры

Муравьёв Константин Николаевич
Вселенная EVE Online
Фантастика:
фэнтези
5.86
рейтинг книги
Закрытые Миры