Универсальность и (versus) наследование
Последующий материал и его появление в приложении требует некоторых пояснений. Начальным толчком, приведшим в итоге к появлению этой книги, было исследование, проведенное в 1984 году при подготовке курса для студентов "Концепции в языках программирования", в котором я сравнивал "горизонтальный" механизм универсальности с "вертикальным" механизмом наследования, введенным в Simula. Первый механизм модульного расширения рассматривался на примере родовых языков, таких как Ada, Z, LPG. Анализировалось, чем отличаются эти техники, в чем они соревнуются, в чем дополняют друг друга. Это привело к статье с одноименным данному приложению названием [M1986], представленной на конференции OOPSLA, и к главе в первом издании этой книги.
При подготовке второго издания я полагал, что универсальность и наследование теперь достаточно хорошо понятны и им уделено достаточное внимание в остальной части книги. Поэтому глава была удалена как слишком специальная и полезная в основном для читателей, интересующихся проблемами разработки языков или ОО-теории. Однако анализ публикаций показывает, что данная проблема до сих пор многих приводит в замешательство. Это особенно проявляется в контексте C++, где множество людей ведет поиск рекомендаций, когда следует использовать "шаблоны", а когда наследование. Поэтому такое обсуждение должно присутствовать в общем рассмотрении объектной технологии, хотя бы в виде приложения.
Рассматриваемые здесь темы даются в следующем порядке: универсальность, наследование, эмуляция одного из этих механизмов с помощью другого и, в заключение, способы их наилучшего согласования.
Начало обсуждения хорошо знакомо внимательному читателю этой книги, однако необходимо вновь обратиться к основам, чтобы получить полную картину каждого механизма, его возможностей и ограничений. Если погружаться все глубже и глубже, делая короткие остановки в критических точках, перед нашими глазами постепенно предстанет идеальная комбинация универсальности и наследования, вытекающая почти с неизбежностью и дающая нам понять в деталях замечательные отношения между двумя принципиальными методами создания программных модулей, открытых для перемен и адаптации.