Что такое полиморфизм

Полиморфизм – это свойство системы использовать объекты с одинаковым интерфейсом без информации о типе и внутренней структуре объекта.

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

Любое обучение вождению не имело бы смысла, если бы человек, научившийся водить, скажем, ВАЗ 2106 не мог потом водить ВАЗ 2110 или BMW X3. С другой стороны, трудно представить человека, который смог бы нормально управлять автомобилем, в котором педаль газа находится левее педали тормоза, а вместо руля – джойстик.

Всё дело в том, что основные элементы управления автомобиля имеют одну и ту же конструкцию, и принцип действия. Водитель точно знает, что для того, чтобы повернуть налево, он должен повернуть руль, независимо от того, есть там гидроусилитель или нет. Если человеку надо доехать с работы до дома, то он сядет за руль автомобиля и будет выполнять одни и те же действия, независимо от того, какой именно тип автомобиля он использует. По сути, можно сказать, что все автомобили имеют один и тот же интерфейс, а водитель, абстрагируясь от сущности автомобиля, работает именно с этим интерфейсом. Если водителю предстоит ехать по немецкому автобану, он, вероятно выберет быстрый автомобиль с низкой посадкой, а если предстоит возвращаться из отдалённого маральника в Горном Алтае после дождя, скорее всего, будет выбран УАЗ с армейскими мостами. Но, независимо от того, каким образом будет реализовываться движение и внутреннее функционирование машины, интерфейс останется прежним.

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

  • ad hoc, функция ведет себя по разному для разных типов аргументов (например, функция draw() — рисует по разному фигуры разных типов);
  • параметрический, функция ведет себя одинаково для аргументов разных типов (например, функция add() — одинаково кладет в контейнер элементы разных типов).

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

Пример:

Давайте представим, что нам в программе нужно описать пользователя, который может пользоваться любыми моделями телефона, чтобы позвонить другому пользователю. Вот как можно это сделать:

public class User {
    private String name;

    public User(String name) {
        this.name = name;
    }

    public void callAnotherUser(int number, AbstractPhone phone) {
// вот он полиморфизм - использование в коде абстактного типа AbstractPhone phone!
        phone.call(number);
    }
}

Теперь опишем различные модели телефонов. Одна из первых моделей телефонов:

public class ThomasEdisonPhone extends AbstractPhone {

    public ThomasEdisonPhone(int year) {
        super(year);
    }

    @Override
    public void call(int outputNumber) {
        System.out.println("Вращайте ручку");
        System.out.println("Сообщите номер абонента, сэр");
    }

    @Override
    public void ring(int inputNumber) {
        System.out.println("Телефон звонит");
    }
}

Обычный стационарный телефон:

public class Phone extends AbstractPhone {

    public Phone(int year) {
        super(year);
    }

    @Override
    public void call(int outputNumber) {
        System.out.println("Вызываю номер" + outputNumber);
    }

    @Override
    public void ring(int inputNumber) {
        System.out.println("Телефон звонит");
    }
}

И, наконец, крутой видеотелефон:

public class VideoPhone extends AbstractPhone {

    public VideoPhone(int year) {
        super(year);
    }

    @Override
    public void call(int outputNumber) {
        System.out.println("Подключаю видеоканал для абонента " + outputNumber);
    }

    @Override
    public void ring(int inputNumber) {
        System.out.println("У вас входящий видеовызов..." + inputNumber);
    }
}

Создадим объекты в методе main() и протестируем метод callAnotherUser:

AbstractPhone firstPhone = new ThomasEdisonPhone(1879);
AbstractPhone phone = new Phone(1984);
AbstractPhone videoPhone=new VideoPhone(2018);
User user = new User("Андрей");
user.callAnotherUser(224466,firstPhone);
// Вращайте ручку
//Сообщите номер абонента, сэр
user.callAnotherUser(224466,phone);
//Вызываю номер 224466
user.callAnotherUser(224466,videoPhone);
//Подключаю видеоканал для абонента 224466

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

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

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

Oct. 21, 2023, Источник

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

1. Статический (компиляционный) полиморфизм: Реализуется с помощью перегрузки методов и операторов. При перегрузке методов методы в одном классе имеют одинаковое имя, но различаются количеством и типом параметров. Компилятор определяет, какой метод вызывать, исходя из аргументов вызова метода.

   Пример:

   public class Example {
       public void display(int a) {
           System.out.println("Число: " + a);
       }
       public void display(String a) {
           System.out.println("Строка: " + a);
       }
   }

2. Динамический (выполнения) полиморфизм: Реализуется с помощью переопределения методов. В этом случае подклассы имеют методы, которые имеют такое же имя и сигнатуру, как и в суперклассе, но реализация методов может отличаться. Какой метод будет вызван, определяется во время выполнения программы, основываясь на типе объекта.

   Пример:

   class Animal {
       void sound() {
           System.out.println("Животное издает звук");
       }
   }
   class Dog extends Animal {
       @Override
       void sound() {
           System.out.println("Собака лает");
       }
   }

   Использование:
   Animal myAnimal = new Dog();
   myAnimal.sound(); // Выведет: Собака лает

Зачем нужен полиморфизм?

  • Гибкость и расширяемость кода: Позволяет писать более обобщенный код, который может работать с объектами разных классов. Это упрощает добавление новых классов, которые могут использоваться существующим кодом без его изменения.
  • Уменьшение связности: Помогает снизить зависимость между компонентами системы, поскольку компоненты могут взаимодействовать друг с другом через общие интерфейсы, не заботясь о конкретной реализации.
  • Сокрытие реализации: Клиентский код может использовать интерфейс без знания о внутренней реализации объекта, что повышает безопасность и модульность программы.

Полиморфизм является ключевым элементом объектно-ориентированного программирования, обеспечивая гибкость и возможности для масштабирования и модификации программ без значительного переписывания кода.

Feb. 27, 2024, easyoffer