- •Введение
- •Как получить исходные тексты
- •Что требуется знать для чтения книги
- •Предисловие к первому изданию
- •Благодарности
- •1.3.Новая парадигма
- •Что читать дальше
- •Упражнения
- •2.7.3.Зацепление и связность
- •2.9. Выбор представления данных
- •Упражнения
- •Глава 3 Классы и методы
- •Упражнения
- •Глава 4 Сообщения, экземпляры и инициализация
- •Упражнения
- •Глава 5 Учебный пример: задача о восьми ферзях
- •Упражнения
- •Глава 6 Учебный пример: игра «Бильярд»
- •Упражнения
- •Глава 7 Наследование
- •7.6.Издержки наследования
- •Упражнения
- •Глава 8 Учебный пример: Пасьянс
- •8.4.1.Основание SuitPile
- •8.4.2.Колода DeckPile
- •Упражнения
- •9.1.1. «Быть экземпляром» и «включать как часть»
- •Упражнения
- •Глава 10 Подклассы и подтипы
- •Упражнения
- •Глава 11 Замещение и уточнение
- •Упражнения
- •Глава 12 Следствия наследования
- •Упражнения
- •Глава 13 Множественное наследование
- •13.1.Комплексные числа
- •Литература для дальнейшего чтения
- •Упражнения
- •Глава 14 Полиморфизм
- •Полиморфные переменные
- •Виртуальное и невиртуальное переопределение
- •Параметрическая перегрузка
- •Отложенные методы в C++
- •Обобщенные функции и шаблоны
- •Полиморфные переменные
- •Отложенные методы в Object Pascal
- •Полиморфные переменные
- •Отложенные методы в Objective-C
- •Полиморфные переменные
- •Отложенные методы в Smalltalk
- •Упражнения
- •Глава 15 Учебный пример: контейнерные классы
- •Упражнения
- •Глава 16 Пример: STL
- •Упражнения
- •Глава 17 Видимость и зависимость
- •Родственные экземпляры
- •Дружественные функции
- •Пространства имен
- •Постоянные члены
- •Упражнения
- •Глава 18 Среды и схемы разработки
- •18.1.1. Java API
- •Упражнения
- •19.5.Класс application
- •19.5.1.Класс button
- •Упражнения
- •Глава 20 Новый взгляд на классы
- •20.2.2.Класс Class
- •Упражнения
- •Глава 21 Реализация объектно-ориентированных языков
- •Литература для дальнейшего чтения
- •Упражнения
- •А.1. «Задача о восьми ферзях» на языке Apple Object Pascal
- •A.3. «Задача о восьми ферзях» на языке Java
- •A.3.1. HTML-файл для апплета Java
- •A.4. «Задача о восьми ферзях» на языке Objective-C
- •A.5. «Задача о восьми ферзях» на языке Smalltalk
- •Б.1. Версия без использования наследования
- •Б.2. Версия с использованием наследования
- •Глоссарий
converted to PDF by BoJIoc
Отложенные методы в Object Pascal
Как мы отметили в главе 7, версии Apple и Borland языка Object Pascal отличаются тем, как они указывают на переопределение метода. В Object Pascal версии Apple ключевое слово override помещается в описание метода дочернего класса. Версия Delphi требует ключевых слов override и virtual в описании метода в родительском классе.
Язык Object Pascal версии Apple не поддерживает отложенные методы. Они реализуются в виде процедуры, генерирующей сообщение об ошибке:
type
Shape = object corner : Point; procedure draw();
...
end;
Circle = object (Shape) radius : integer; procedure draw(); override;
...
end;
procedure Shape.draw(); begin
writeln('descendant should define draw'); halt();
end;
В языке Delphi Pascal метод может быть объявлен как отложенный c ключевым словом abstract, следующим за ключевым словом virtual (или dynamic) при описании в родительском классе. Для абстрактного метода не задается тело. В отличие от C++ можно создать объект, класс которого имеет все еще не переопределенные абстрактные методы. То есть язык Delphi поддерживает абстрактные методы, но не абстрактные классы.
type
class TShape
procedure draw; virtual; abstract;
...
end;
class TTriangle (TShape) procedure draw; override;
...
end;
14.9.4. Полиморфизм в Objective-C
Полиморфные переменные
При описании с ключевым словом id все переменные в Objective-C полиморфны и поэтому могут содержать любое значение. При описании с конкретным классом переменные имеют все свойства (хорошие и не очень) переменных языка C++.
Отложенные методы в Objective-C
Не требуется специального указания для описания отложенного метода в языке Objective- C. Чтобы помочь в создании таких методов, в классе Object определяется сообщение subclassResponsibility (которое тем самым доступно для всех объектов). Оно просто печатает строку, показывающую, что выполняемое действие должно быть переопределено в подклассе.
converted to PDF by BoJIoc
Отложенный метод draw для класса Shape может быть записан, к примеру, следующим образом:
@implementation Shape : Object
...
- draw { return [ self subclassResponsibility ]; }
...
@end
14.9.5. Полиморфизм в Smalltalk
Полиморфные переменные
Поскольку Smalltalk — это язык с динамическими типами данных, все переменные являются полиморфными. Они могут хранить любое значение.
Отложенные методы в Smalltalk
Вязыке Smalltalk не требуется специального указания, чтобы описать отложенный метод.
Вклассе Object определено сообщение subclassResponsibility (тем самым доступное любым другим объектам). Оно печатает строку, показывающую, что для некоторого подкласса вызывается действие, которое должно быть переопределено.
Отложенный метод draw для класса Shape может быть записан следующим образом:
draw
" дочерние классы должны переопределять этот метод " self subclassResponsibility
14.10. Эффективность и полиморфизм
Программирование всегда сводится к компромиссу. В частности, полиморфизм подразумевает компромисс между простотой разработки и использования, читаемостью кода и эффективностью. В значительной степени эффективность уже была нами рассмотрена: выяснилось, что потери в эффективности не столь велики. Однако было бы непростительным не принимать полностью во внимание этот момент.
Функция (подобная методу between:and:, описанному в предыдущем разделе), которая не знает тип своего аргумента, вряд ли будет столь же эффективна, как функция, владеющая полной информацией. Сравнительный тест может обнаружить лишь несколько дополнительных команд на языке ассемблера в случае, если аргументом является целое число. Если же аргумент — это объект-точка, то требуются гораздо более продолжительные действия. Тем не менее преимущества быстрой разработки,
самосогласованного поведения приложения и возможность многократно использовать программный код обычно значат больше, чем небольшие потери в эффективности.
Упражнения
1.Как вы думаете, следует ли рассматривать значение nil в языке Pascal, или аналогичную величину NULL в C как полиморфный объект? Обоснуйте свой ответ.
2.Какие еще операции (за исключением арифметических) обычно являются перегруженными в традиционных языках программирования (Pascal и C)?
3.Проведите трассировку методов и классов при вычислении выражения: anInteger between: 7 and: 11