Что такое связывание (binding) в контексте полиморфизма?

«Что такое связывание (binding) в контексте полиморфизма?» — вопрос из категории ООП, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Связывание (binding) — это процесс определения того, какая конкретная реализация метода будет выполнена при его вызове. В объектно-ориентированном программировании различают два основных типа связывания:

  • Раннее (статическое) связывание: Происходит во время компиляции. Компилятор однозначно определяет вызываемый метод. Применяется для private, final, static методов и перегрузки методов (overloading).
  • Позднее (динамическое) связывание: Происходит во время выполнения (runtime). Конкретный метод определяется на основе фактического типа объекта. Это основа полиморфизма и переопределения методов (overriding).

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

Пример на Java:

class Animal {
    void makeSound() {
        System.out.println("Some generic animal sound");
    }
}

class Dog extends Animal {
    @Override
    void makeSound() { // Этот метод будет выбран при позднем связывании
        System.out.println("Bark!");
    }
}

class Cat extends Animal {
    @Override
    void makeSound() {
        System.out.println("Meow!");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal myPet = new Dog(); // Ссылка типа Animal, объект типа Dog
        myPet.makeSound(); // Вывод: "Bark!"
        // JVM во время выполнения (позднее связывание) определяет,
        // что нужно вызвать Dog.makeSound(), а не Animal.makeSound().

        myPet = new Cat();
        myPet.makeSound(); // Вывод: "Meow!" (снова позднее связывание)
    }
}