- •Введение
- •Как получить исходные тексты
- •Что требуется знать для чтения книги
- •Предисловие к первому изданию
- •Благодарности
- •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
языков программирования настаивают, что большинство таких ошибок может быть отловлено на этапе компиляции для языка со статическим связыванием методов. Эта точка зрения оспаривается (как и следовало ожидать) сторонниками динамического программирования.
Тем самым нам приходится решать, что более важно: эффективность или гибкость, правильность или легкость использования. Брэд Кокс [Cox 1986] настаивает, что решение зависит как от уровня абстракции программы, так и от того, являемся ли мы производителями или потребителями программной системы. Кокс утверждает, что объектно-ориентированное программирование будет основным (хотя и не единственным) средством в «революции в области программной индустрии».
Точно так же как в девятнадцатом веке индустриальная революция стала возможна только после разработки взаимозаменяемых деталей, так и целью
программной революции является конструирование многократно используемых и надежных абстрактных компонент высокого уровня для программного обеспечения, из которых собираются реальные приложения.
Эффективность — главное, о чем следует думать на низком уровне (Кокс называет этот уровень «абстракцией уровня транзисторов» («gate-level abstractions») по аналогии с электроникой). По мере повышения уровня абстракции (до интегральных микросхем и готовых плат) гибкость становится более существенной.
Эффективность программы является первостепенной заботой разработчика. Для потребителя, заинтересованного в комбинировании программных систем, гибкость может быть более важной.
Итак, нет единственно правильного ответа на вопрос, какая из техник связывания является более подходящей. Все зависит от конкретной ситуации.
Упражнения
∙Язык Object Pascal использует и статические типы данных, и динамическое связывание. Объясните, почему обратная ситуация (динамические типы данных и статическое связывание сообщений с методами) невозможна.
∙Проиллюстрируйте, почему в объектно-ориентированных языках программирования со статическими типами данных (например, C+ или Object Pascal) компилятор проверяет, чтобы значение переменной родительского класса не присваивалось переменной, описанной как экземпляр подкласса.
∙Подумайте о том, стоит ли проверка ошибок, которая становится возможной при статических типах данных, проигрыша в гибкости. Насколько важны контейнерные классы?
∙Где не срабатывает аналогия Брэда Кокса между аппаратным и программным обеспечением? Что препятствует разработке переносимых надежных программных компонент?