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

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

Раннее связывание

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

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

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

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

Поздняя привязка

Несмотря на предыдущий раздел, есть и другие способы для этого случая полиморфизм может сработать. Рассмотрим, например, язык 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. [истина, ложь] + [ложь, истина] = [истина, ложь, ложь, истина]
  6. "баб" + "оон" = "бабуин"

Перегрузка

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

Таким образом, название + фактически относится к трем или четырем совершенно различным функциям. Это пример перегрузка. (Обратите внимание, что строковые типы, используемые в последнем случае, сами по себе не поддаются программисту. естественно предполагается конкатенация, а не сложение; рассмотрите «123» + «456», что, как можно разумно ожидать, даст «579». Следовательно, перегрузка может обеспечивать различное значение или семантику для операции, а также различные реализации.)

использованная литература

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