← Назад к вопросам

В чём разница между перегрузкой (overloading) и переопределением (overriding) методов?

2.0 Middle🔥 191 комментариев
#ООП

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Разница между перегрузкой и переопределением методов

Это два фундаментальных концепта Java, которые часто путают начинающие разработчики. Оба используют одинаковые названия методов, но работают совершенно по-разному.

Перегрузка (Overloading)

Перегрузка — это способность класса иметь несколько методов с одинаковым названием, но разными параметрами. Решение о том, какой метод вызвать, принимается на этапе компиляции (статическое связывание).

Критерии для перегрузки:

  • Одинаковое имя метода
  • Разное количество параметров ИЛИ
  • Разные типы параметров ИЛИ
  • Разный порядок типов параметров
  • Возвращаемый тип НЕ влияет на перегрузку
public class Calculator {
    // Перегрузка 1: два int
    public int add(int a, int b) {
        return a + b;
    }

    // Перегрузка 2: два double
    public double add(double a, double b) {
        return a + b;
    }

    // Перегрузка 3: три int
    public int add(int a, int b, int c) {
        return a + b + c;
    }

    // Перегрузка 4: String и int
    public void add(String message, int value) {
        System.out.println(message + value);
    }
}

// Использование
Calculator calc = new Calculator();
calc.add(5, 10);              // Вызовет перегрузку 1
calc.add(5.5, 10.5);          // Вызовет перегрузку 2
calc.add(5, 10, 15);          // Вызовет перегрузку 3
calc.add("Результат: ", 100); // Вызовет перегрузку 4

Переопределение (Overriding)

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

Правила для переопределения:

  • Метод должен быть унаследован из суперкласса
  • Одинаковое имя метода
  • Одинаковые параметры (тип, количество, порядок)
  • Одинаковый или совместимый возвращаемый тип (ковариантность)
  • Уровень доступа не может быть более ограниченным
  • Не может выбросить больше checked exception, чем исходный метод
  • Используется аннотация @Override
// Суперкласс
public class Animal {
    public void sound() {
        System.out.println("Издает звук");
    }

    public void move() {
        System.out.println("Движется");
    }
}

// Подкласс 1
public class Dog extends Animal {
    @Override
    public void sound() {
        System.out.println("Гавкает!");
    }

    @Override
    public void move() {
        System.out.println("Бежит на четырех лапах");
    }
}

// Подкласс 2
public class Cat extends Animal {
    @Override
    public void sound() {
        System.out.println("Мяукает!");
    }

    @Override
    public void move() {
        System.out.println("Ходит грациозно");
    }
}

// Использование - полиморфизм
Animal dog = new Dog();
Animal cat = new Cat();

dog.sound();  // Выведет: "Гавкает!"
cat.sound();  // Выведет: "Мяукает!"

Сравнительная таблица

ХарактеристикаOverloading (Перегрузка)Overriding (Переопределение)
НаследованиеНе требуетсяОбязательно
ПараметрыДолжны отличатьсяДолжны быть одинаковыми
Возвращаемый типМожет быть любымДолжен быть совместимым или идентичным
Имя методаОдинаковоеОдинаковое
СвязываниеСтатическое (compile-time)Динамическое (runtime)
Область видимостиОдин классКлассы в иерархии наследования
ИспользованиеУдобство вызова, читаемостьПолиморфизм, расширяемость

Практический пример

public class Shape {
    // Переопределяемый метод
    public void draw() {
        System.out.println("Рисует фигуру");
    }

    // Перегруженные методы
    public void calculateArea(double radius) {
        System.out.println("Площадь круга: " + (Math.PI * radius * radius));
    }

    public void calculateArea(double width, double height) {
        System.out.println("Площадь прямоугольника: " + (width * height));
    }
}

public class Circle extends Shape {
    @Override
    public void draw() {
        System.out.println("Рисует круг");
    }
}

public class Rectangle extends Shape {
    @Override
    public void draw() {
        System.out.println("Рисует прямоугольник");
    }
}

// Демонстрация
Shape circle = new Circle();
Shape rectangle = new Rectangle();

circle.draw();     // Выведет: "Рисует круг" (overriding)
rectangle.draw();  // Выведет: "Рисует прямоугольник" (overriding)

circle.calculateArea(5);        // Перегрузка: одна переменная
rectangle.calculateArea(4, 6);  // Перегрузка: две переменные

Заключение

Перегрузка позволяет использовать один метод с разными наборами параметров в одном классе, улучшая читаемость и удобство API. Переопределение реализует полиморфизм, позволяя подклассам переопределять поведение родительского класса и создавая гибкие иерархии наследования. Оба механизма критически важны для практического программирования на Java.

В чём разница между перегрузкой (overloading) и переопределением (overriding) методов? | PrepBro