Специальный полиморфизм

Из Википедии, бесплатной энциклопедии

В языках программирования . специальный полиморфизм [1] — это своего рода полиморфизм , при котором полиморфные функции могут применяться к аргументам разных типов, поскольку полиморфная функция может обозначать ряд различных и потенциально гетерогенных реализаций в зависимости от типа аргумента(ов), к которому она применяется. Применительно к объектно-ориентированным или процедурным концепциям это также известно как перегрузка функций или перегрузка операторов . Термин ad hoc в этом контексте не является уничижительным; это просто относится к тому факту, что этот тип полиморфизма не является фундаментальной особенностью системы типов . В этом отличие от параметрического полиморфизма , в котором полиморфные функции записываются без упоминания какого-либо конкретного типа и, таким образом, могут прозрачно применять одну абстрактную реализацию к любому количеству типов. Эта классификация была введена Кристофером Стрейчи в 1967 году.

Раннее связывание [ править ]

Специальный полиморфизм — это механизм диспетчеризации : управление, проходящее через одну именованную функцию, передается различным другим функциям без необходимости указывать точную вызываемую функцию. Перегрузка позволяет определять несколько функций разных типов с одним и тем же именем; компилятор интерпретатор или автоматически гарантирует вызов правильной функции. Таким образом, можно было бы написать функции, добавляющие списки целых чисел , списки строк , списки действительных чисел и т. д., и все они будут называться «добавлением» — и правильная функция добавления будет вызываться в зависимости от типа добавляемых списков. Это отличается от параметрического полиморфизма, при котором функцию необходимо написать в общем виде , чтобы работать с любым типом списка. Используя перегрузку, можно заставить функцию выполнять две совершенно разные вещи в зависимости от типа передаваемых ей входных данных; это невозможно при параметрическом полиморфизме. Другой взгляд на перегрузку состоит в том, что подпрограмма однозначно идентифицируется не по ее имени, а по комбинации ее имени и количества, порядка и типов ее параметров.

Этот тип полиморфизма распространен в объектно-ориентированных языках программирования, многие из которых позволяют перегружать операторы аналогично функциям (см. Перегрузка операторов ). Некоторые языки, которые не являются динамически типизированными и лишены специального полиморфизма (включая классы типов), имеют более длинные имена функций, такие как print_int, print_stringи т. д. Это можно рассматривать как преимущество (более описательное) или недостаток (слишком многословное) в зависимости от точки зрения.

Преимущество, которое иногда дает перегрузка, заключается в появлении специализации, например, функция с одним и тем же именем может быть реализована несколькими различными способами, каждый из которых оптимизирован для определенных типов данных, с которыми она работает. Это может обеспечить удобный интерфейс для кода, который необходимо специализировать для различных ситуаций по соображениям производительности. Обратной стороной является то, что система типов не может гарантировать согласованность различных реализаций.

Поскольку перегрузка выполняется во время компиляции, она не заменяет позднее связывание , как это происходит при полиморфизме подтипирования .

Позднее связывание [ править ]

Несмотря на предыдущий раздел, существуют и другие способы специального реализации полиморфизма. Рассмотрим, например, язык Smalltalk. В Smalltalk перегрузка выполняется во время выполнения, поскольку методы («реализация функции») для каждого перегруженного сообщения («перегруженная функция») разрешаются перед их выполнением. Это происходит во время выполнения, после компиляции программы. Таким образом, полиморфизм задается полиморфизмом подтипирования , как и в других языках, а его функциональность также расширяется за счет специального полиморфизма во время выполнения.

Более пристальный взгляд также покажет, что Smalltalk предоставляет несколько иную разновидность специального полиморфизма. Поскольку в Smalltalk есть модель выполнения с поздним связыванием и поскольку он предоставляет объектам возможность обрабатывать непонятные сообщения, можно реализовать функциональность с использованием полиморфизма без явной перегрузки конкретного сообщения. Возможно, это не совсем рекомендуемая практика для повседневного программирования, но она может быть весьма полезна при реализации прокси.

Кроме того, хотя в общих чертах перегрузка общих методов классов и конструкторов не считается полиморфизмом, существуют более унифицированные языки, в которых классы являются обычными объектами. Например, в Smalltalk классы являются обычными объектами. В свою очередь, это означает, что сообщения, отправляемые классам, могут быть перегружены, а также возможно создавать объекты, которые ведут себя как классы, без наследования их классов от иерархии классов. Это эффективные методы, которые можно использовать, чтобы воспользоваться мощными возможностями отражения Smalltalk . Подобные механизмы также возможны в таких языках, как селф и новояз .

Пример [ править ]

Представьте себе оператора + который можно использовать следующими способами:

  1. 1 + 2 = 3
  2. 3.14 + 0.0015 = 3.1415
  3. 1 + 3.7 = 4.7
  4. [1, 2, 3] + [4, 5, 6] = [1, 2, 3, 4, 5, 6]
  5. [true, false] + [false, true] = [true, false, false, true]
  6. "bab" + "oon" = "baboon"

Для обработки этих шести вызовов функций необходимы четыре разных фрагмента кода (или три, если строки считать списками символов):

Таким образом, имя +на самом деле относится к трем или четырем совершенно различным функциям. Это пример перегрузки или, точнее, перегрузки оператора .

Обратите внимание на неоднозначность типов строк, используемых в последнем случае. Учитывать "123" + "456"в котором программист, естественно, мог бы предположить сложение, а не конкатенацию. Они могут ожидать "579" вместо "123456". Таким образом, перегрузка может придавать операции различное значение или семантику, а также различные реализации.

См. также [ править ]

Ссылки [ править ]

  1. ^ К. Стрейчи, Фундаментальные концепции языков программирования . Конспекты лекций для Международной летней школы компьютерного программирования, Копенгаген, август 1967 г.