Что такое полиморфизм в ООП? Приведите пример на Java.

Ответ

Полиморфизм — это способность объектов с одинаковой спецификацией (интерфейсом/родительским классом) иметь различную реализацию. В Java существует два основных типа:

  1. Полиморфизм во время выполнения (Runtime): Переопределение методов (override).
  2. Полиморфизм во время компиляции (Compile-time): Перегрузка методов (overload).

Пример runtime-полиморфизма через переопределение метода:

// Базовый класс (общий тип)
class Shape {
    void draw() {
        System.out.println("Drawing a generic shape");
    }
}

// Производные классы
class Circle extends Shape {
    @Override
    void draw() {
        System.out.println("Drawing a circle");
    }
}

class Square extends Shape {
    @Override
    void draw() {
        System.out.println("Drawing a square");
    }
}

public class PolymorphismDemo {
    public static void main(String[] args) {
        // Ссылка типа Shape, объекты разных типов
        Shape shape1 = new Circle(); // Upcasting
        Shape shape2 = new Square(); // Upcasting
        Shape shape3 = new Shape();

        // Один и тот же метод вызывается, но поведение разное
        shape1.draw(); // Вывод: Drawing a circle
        shape2.draw(); // Вывод: Drawing a square
        shape3.draw(); // Вывод: Drawing a generic shape
    }
}

Ключевой момент: Компилятор видит вызов shape1.draw() как метод класса Shape, но JVM во время выполнения определяет фактический тип объекта (Circle) и выполняет его версию метода. Это и есть полиморфизм.

Ответ 18+ 🔞

Да ты посмотри, какая хуйня интересная! Ну вот смотри, полиморфизм, блядь. Это ж как в жизни: вроде все люди, а один рисует, другой поёт, третий вообще хуй знает чем занимается, но все они — люди, ёпта!

Вот представь, есть у тебя общий типаж, эталон, шаблон. Называется, допустим, Shape — фигура. И у неё есть метод draw() — нарисовать. Ну и что она рисует? А нихуя конкретного, просто «рисую какую-то фигуру». Скукота, блядь.

А теперь появляются наследнички, выскочки. Circle — кружочек, и Square — квадратик. И каждый из них такой: «Да пошёл ты нахуй со своим общим рисованием! Я буду рисовать по-своему!». И переопределяет этот самый метод draw().

И вот тут начинается магия, ебать мои старые костыли! В коде ты можешь объявить переменную типа Shape, но запихнуть в неё объект Circle. Компилятор смотрит и думает: «Ну окей, Shape так Shape, похую». А когда программа уже бежит, и доходит до вызова shape.draw(), система (JVM, эта сука хитрая) смотрит, а что там на самом деле внутри-то лежит? А там — Circle! И она вызывает не общий метод Shape, а конкретный, переопределённый метод Circle! Вот это и есть полиморфизм времени выполнения, или, как умники говорят, runtime polymorphism. Один интерфейс — «нарисовать фигуру», а реализаций — овердохуища разных!

А есть ещё полиморфизм на этапе компиляции — это когда ты один и тот же метод называешь одинаково, но с разными параметрами (перегрузка). Компилятор, тот ещё зануда, смотрит, какие аргументы ты туда суёшь, и сам решает, какую именно версию метода тебе подсунуть. Но это уже, как говорится, совсем другая история, в рот меня чих-пых.

Главное, чувак, запомни суть: полиморфизм — это когда ты говоришь «сделай что-то», а система, ебáаать, сама догадывается, КАК именно это сделать, в зависимости от того, с кем она на самом деле имеет дело. Красота, да и только!