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

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

Жанры

Программирование на 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++. Это три ключевых концепции: полиморфизм, динамический контроль типов и динамическое связывание.

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

Геном хищника. Книга пятая

Гарцевич Евгений Александрович
5. Я - Легенда!
Фантастика:
рпг
фэнтези
попаданцы
6.00
рейтинг книги
Геном хищника. Книга пятая

"Дальние горизонты. Дух". Компиляция. Книги 1-25

Усманов Хайдарали
Собрание сочинений
Фантастика:
фэнтези
боевая фантастика
попаданцы
5.00
рейтинг книги
Дальние горизонты. Дух. Компиляция. Книги 1-25

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

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

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

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

Эволюция мага

Лисина Александра
2. Гибрид
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Эволюция мага

Кодекс Охотника. Книга X

Винокуров Юрий
10. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
6.25
рейтинг книги
Кодекс Охотника. Книга X

Хозяин Теней 7

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

Черная метка

Лисина Александра
7. Гибрид
Фантастика:
технофэнтези
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Черная метка

Гранит науки. Том 3

Зот Бакалавр
3. Героями не становятся, ими умирают
Фантастика:
фэнтези
боевая фантастика
5.00
рейтинг книги
Гранит науки. Том 3

Неучтенный элемент. Том 5

NikL
5. Антимаг. Вне системы
Фантастика:
фэнтези
5.00
рейтинг книги
Неучтенный элемент. Том 5

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

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

Я все еще не князь. Книга XV

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

Товарищ "Чума" 4

lanpirot
4. Товарищ "Чума"
Фантастика:
городское фэнтези
альтернативная история
5.00
рейтинг книги
Товарищ Чума 4

Последний реанорец. Том III

Павлов Вел
2. Высшая Речь
Фантастика:
фэнтези
попаданцы
5.25
рейтинг книги
Последний реанорец. Том III