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

Ответ

Полиморфизм в Java — это принцип ООП, позволяющий объектам разных классов обрабатываться через общий интерфейс (родительский класс или интерфейс). Это повышает гибкость и расширяемость кода.

Существует два основных типа:

  1. Полиморфизм времени выполнения (Runtime / динамический): достигается через переопределение методов (method overriding).

    • Метод в подклассе переопределяет метод суперкласса.
    • Конкретная реализация метода выбирается JVM во время выполнения на основе типа фактического объекта.
    class Animal {
        void makeSound() {
            System.out.println("Some sound");
        }
    }
    
    class Dog extends Animal {
        @Override
        void makeSound() {
            System.out.println("Bark");
        }
    }
    
    class Cat extends Animal {
        @Override
        void makeSound() {
            System.out.println("Meow");
        }
    }
    
    // Использование
    Animal myAnimal = new Dog();
    myAnimal.makeSound(); // Вывод: "Bark" (вызван метод Dog)
    myAnimal = new Cat();
    myAnimal.makeSound(); // Вывод: "Meow" (вызван метод Cat)
  2. Полиморфизм времени компиляции (Compile-time / статический): достигается через перегрузку методов (method overloading).

    • В одном классе существует несколько методов с одним именем, но разными параметрами.
    • Нужный метод выбирается компилятором на основе сигнатуры вызова.
    class Calculator {
        int add(int a, int b) {
            return a + b;
        }
        double add(double a, double b) {
            return a + b;
        }
        int add(int a, int b, int c) {
            return a + b + c;
        }
    }

Почему это важно: Полиморфизм позволяет писать код, который работает с абстракциями (например, Animal), а не с конкретными реализациями (Dog, Cat). Это упрощает добавление новых типов и соблюдение принципа открытости/закрытости (Open/Closed Principle).

Ответ 18+ 🔞

А, слушай, вот эта ваша хуйня с полиморфизмом! Ну, внатуре, это как в жизни, блядь. Вот представь: есть у тебя понятие «говорящее существо». И ты говоришь: «эй, говорящее существо, скажи что-нибудь!». А оно тебе в ответ может «гав-гав», а может «мяу», а может ещё какую-то пиздобратию нести. А тебе, в общем-то, похуй, кто конкретно там отозвался — главное, что оно умеет говорить. Вот это и есть полиморфизм времени выполнения, ёпта! Объект сам разберётся, какой метод вызвать, когда уже всё запущено. JVM, блядь, как мудрый начальник, смотрит: ага, ссылка типа Animal, а на самом деле там Dog сидит — ну значит, и метод собачий дерни. Хитро, блядь!

А есть ещё полиморфизм времени компиляции — это когда ты заранее, ещё до запуска, пишешь кучу методов с одним названием, но с разными параметрами. Компилятор, этот дотошный зануда, смотрит: ага, ты передал два int — ну окей, значит, вызовется первый add. Передал три int — ну всё, поезд ушёл, вызовется третий. Всё решается на берегу, ещё до того, как твой код вообще побежал. Как в столовой: если у тебя в руках один поднос — ты проходишь в один коридор, если два — тебя уже в другой отправят, блядь. Статично и предсказуемо.

И вся эта, блядь, магия нужна для того, чтобы не сойти с ума, когда у тебя объектов дохуища разных. Вместо того чтобы для каждой твари писать отдельный if, ты просто работаешь с общей абстракцией. Захотел добавить новый класс Parrot — пожалуйста, расширяй Animal, переопределяй makeSound() на «Попка дурак!», и весь твой старый код, который умеет работать с Animal, уже будет с попугаем дружить. Красота, блядь, а не принцип! Открытости/закрытости, ёпта, в действии. Новое добавляешь, а старое не трогаешь и не ломаешь. Умно, сука.