В информатике (Computer Science) есть такое понятие, как полиморфизм. Возможно, вы про него слышали в связи с объектно-ориентированным программированием. На самом деле полиморфизм – это общее название для немного разных концепций, поэтому важно понимать то, о чем мы говорим в данном конкретном случае. Существует несколько видов полиморфизмов:
- Ad-hoc полиморфизм.
- Полиморфизм подтипов (subtyping).
- Параметрический полиморфизм.
В данном уроке мы поговорим про параметрический полиморфизм и немного про ad-hoc. Параметрический полиморфизм позволяет одному куску кода работать идентично для разных типов данных. Логика этого кода работает независимо от типа, для которого он выполняется. Например, логика кода добавления элемента в список никак не зависит от того, какого типа этот элемент.
var items = new LinkedList<>();
items.add("Sun");
Именно это и делают дженерики. Дженерики – это специфичное название для Java, но в его основе лежит параметрический полиморфизм. То есть дженерики – это реализация параметрического полиморфизма для Java. Зачем это нужно знать? Понимая суть вещей, проще читать книги и документацию, общаться с другими программистами, в том числе на других языках. И конечно же, проще учить другие языки. Реализация параметрического полиморфизма есть практически во всех популярных языках. В некоторых она не нужна, так как там такое поведение работает изначально.
// Для примера код на JavaScript
// Здесь параметрический полиморфизм не нужен
// Заполняем массив (он же список в Java)
var numbers = [];
numbers.push(10);
numbers.push(20);
Программирование с использованием дженериков (или параметрического полиморфизма) называется обобщенным программированием (generic programming). Классы и интерфейсы называются обобщенными типами, а методы обобщенными методами. Все эти термины регулярно встречаются в документации, поэтому их важно знать.
Производительность
Параметрический полиморфизм – это теоретическое понятие, а дженерики – конкретная реализация. Поэтому, говоря о дженериках, нас, например, волнует такая вещь, как производительность. Насколько дженерики эффективны? Дженерики не создают нагрузку в рантайме. Компилятор генерирует нужные классы и интерфейсы для конкретных типов, что немного замедляет время компиляции, но на этом все. В результирующем коде все типы будут указаны явно. Это, например, хорошо видно по подсказкам в редакторе, которые показывают тип в каждом конкретном случае.
Отличие от ad-hoc полиморфизма
Параметрический полиморфизм иногда путают с остальными видами, особенно с ad-hoc. ad-hoc полиморфизм в Java – это просто перегрузка методов.
class MathOperations {
public int add(int a, int b) {
return a + b;
}
// Перегруженный метод
public double add(double a, double b) {
return a + b;
}
}
Перегрузка методов создает для каждого указанного типа свой собственный метод, поэтому не выполняется главное требование параметрического полиморфизма, в котором работает один кусок кода. Плюс перегрузка работает с ограниченным набором типов, в отличие от параметрического полиморфизма, для которого мы указываем обобщенный тип, подходящий подо все типы. И, как правило, цель перегрузки – реализовать логику работы над типом, в то время как в параметрическом полиморфизме реализуется логика, независящая от типа.
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.