0 added
0 removed
Original
2026-01-01
Modified
2026-02-26
1
<p>Слово "полиморфизм" в зависимости от контекста может означать разные вещи. Когда о полиморфизме говорят программисты на императивных языках, они, как правило, подразумевают "полиморфизм подтипов". В то же время программисты на функциональных языках имеют в виду "параметрический полиморфизм". О последнем и поговорим.</p>
1
<p>Слово "полиморфизм" в зависимости от контекста может означать разные вещи. Когда о полиморфизме говорят программисты на императивных языках, они, как правило, подразумевают "полиморфизм подтипов". В то же время программисты на функциональных языках имеют в виду "параметрический полиморфизм". О последнем и поговорим.</p>
2
<p><em>В этом уроке появляется код на Java. Не переживайте, если не понимаете его до конца, наша цель - разобраться с концепциями, а не с Java.</em></p>
2
<p><em>В этом уроке появляется код на Java. Не переживайте, если не понимаете его до конца, наша цель - разобраться с концепциями, а не с Java.</em></p>
3
<p>В PHP есть встроенная функция array_merge(), которая объединяет переданные ей массивы:</p>
3
<p>В PHP есть встроенная функция array_merge(), которая объединяет переданные ей массивы:</p>
4
<p>Эта функция объединяет любые массивы, независимо от типа данных, содержащихся внутри. Попробуем реализовать её самостоятельно.</p>
4
<p>Эта функция объединяет любые массивы, независимо от типа данных, содержащихся внутри. Попробуем реализовать её самостоятельно.</p>
5
<p>Посмотрите внимательно на этот код. Выполняются ли в нём какие-либо операции над данными внутри массива? Ответ: нет. Эти данные перекладываются из одного массива в другой, но над ними не происходит никаких действий. Наша новая функция myArrayMerge(), также как и исходная array_merge() может работать с массивами, содержащими любые типы данных.</p>
5
<p>Посмотрите внимательно на этот код. Выполняются ли в нём какие-либо операции над данными внутри массива? Ответ: нет. Эти данные перекладываются из одного массива в другой, но над ними не происходит никаких действий. Наша новая функция myArrayMerge(), также как и исходная array_merge() может работать с массивами, содержащими любые типы данных.</p>
6
<p>Для разработчиков, которые писали только на динамических языках, такое поведение кажется естественным, но в статических языках не всё так просто. Ниже пример определения массивов в Java:</p>
6
<p>Для разработчиков, которые писали только на динамических языках, такое поведение кажется естественным, но в статических языках не всё так просто. Ниже пример определения массивов в Java:</p>
7
<p>В глаза бросается необходимость указывать тип. Для первого массива это int, для второго String. Нельзя создать массив без указания типа его значений. То же самое касается функций, обрабатывающих массивы:</p>
7
<p>В глаза бросается необходимость указывать тип. Для первого массива это int, для второго String. Нельзя создать массив без указания типа его значений. То же самое касается функций, обрабатывающих массивы:</p>
8
<p>Обратите внимание на сигнатуру метода myArrayMerge(): int[] myArrayMerge(int[] first, int[] last). В отличие от варианта на PHP, здесь указано, что входными параметрами являются массивы чисел. То есть для массива строк эта функция работать не будет. Не будет она работать и для всех остальных типов данных.</p>
8
<p>Обратите внимание на сигнатуру метода myArrayMerge(): int[] myArrayMerge(int[] first, int[] last). В отличие от варианта на PHP, здесь указано, что входными параметрами являются массивы чисел. То есть для массива строк эта функция работать не будет. Не будет она работать и для всех остальных типов данных.</p>
9
<p>Что это означает на практике? Очень простую и печальную вещь. Нам придётся реализовывать подобную функцию для<em>каждого типа</em>, при том что алгоритм внутри абсолютно идентичен.</p>
9
<p>Что это означает на практике? Очень простую и печальную вещь. Нам придётся реализовывать подобную функцию для<em>каждого типа</em>, при том что алгоритм внутри абсолютно идентичен.</p>
10
<p>Именно тут нам пригодится параметрический полиморфизм. Статическим языкам приходится вводить в язык специальные конструкции, которые позволяют описывать подобные алгоритмы безотносительно типа параметра. В некоторых языках их называют шаблонами (C++) или дженериками (Java, C#):</p>
10
<p>Именно тут нам пригодится параметрический полиморфизм. Статическим языкам приходится вводить в язык специальные конструкции, которые позволяют описывать подобные алгоритмы безотносительно типа параметра. В некоторых языках их называют шаблонами (C++) или дженериками (Java, C#):</p>
11
<p>В этом коде появляется тип<em>T</em>, что как раз и означает возможность использования с любым типом внутри массива. Теперь функция myArrayMerge работает подобно аналогу из PHP.</p>
11
<p>В этом коде появляется тип<em>T</em>, что как раз и означает возможность использования с любым типом внутри массива. Теперь функция myArrayMerge работает подобно аналогу из PHP.</p>
12
<p>Параметрический полиморфизм даёт возможность писать обобщённые алгоритмы для составных типов, что в некоторых случаях значительно сокращает количество кода. Иногда за это приходится платить сложностью решения, но для большинства типичных операций сложность растёт не сильно. Это видно и по коду выше.</p>
12
<p>Параметрический полиморфизм даёт возможность писать обобщённые алгоритмы для составных типов, что в некоторых случаях значительно сокращает количество кода. Иногда за это приходится платить сложностью решения, но для большинства типичных операций сложность растёт не сильно. Это видно и по коду выше.</p>
13
<p>В динамических языках для реализации обобщённых алгоритмов, параметрический полиморфизм не нужен. Любая коллекция может содержать любые типы данных в любой момент времени. Благодаря этому не требуется вводить дополнительных языковых конструкций и изучать новые концепции.</p>
13
<p>В динамических языках для реализации обобщённых алгоритмов, параметрический полиморфизм не нужен. Любая коллекция может содержать любые типы данных в любой момент времени. Благодаря этому не требуется вводить дополнительных языковых конструкций и изучать новые концепции.</p>
14
<p>В литературе использование параметрического полиморфизма часто называется обобщённым программированием.</p>
14
<p>В литературе использование параметрического полиморфизма часто называется обобщённым программированием.</p>