# 6. Перегрузка методов

## Что такое перегрузка методов

В Java разрешается в одном и том же классе определять два или более метода с одинаковым именем, если только объявления их параметров отличаются. В этом случае методы называются **перегружаемыми**, а сам процесс – **перегрузкой метода** (**method overloading**).

```java
class MyClass {
    
    public void foo() {
        // ... код
    }
    
    public void foo(String s) {
        // ... код
    }
}
```

Если у методов одинаковые имена, как Java узнает, какой именно из них вызывается? Ответ прост: **перегружаемые методы должны отличаться по типу и/или количеству входных параметров**. Даже разного порядка аргументов достаточно для того, чтобы методы считались разными (хотя это не рекомендуется).

**Перегрузка по возвращаемым значениям**

Логично спросить, почему при перегрузке используются только имена классов и списки аргументов? Почему не идентифицировать методы по их возвращаемым значениям?

```java
// ДАННЫЙ КОД ВЫЗОВЕТ ОШИБКУ КОМПИЛЯЦИИ!

class MyClass {

    public int foo() {
        return 0;
    }

    public double foo() {
        return 0;
    }
}
```

Идентифицировать их нельзя, потому что Java в этом случае не может определить, какая версия метода должна выполняться.

При вызове перегружаемого метода для определения нужного варианта в Java используется тип и\или количество аргументов метода. Следовательно, перегружаемые методы должны отличаться по типу и\или количеству их параметров. Возвращаемые типы перегружаемых методов могут отличаться, но самого возвращаемого метода недостаточно, чтобы отличить два разных варианта метода. Когда в исполняющей среде Java встречается вызов перегружаемого метода, в ней просто выполняется тот вариант, параметры которого соответствуют аргументам, указанным в вызове.

**Перегрузка методов позволяет поддерживать принцип «один интерфейс, несколько методов».**

В языках программирования без перегрузки методов, каждому методу должно быть присвоено однозначное имя. Но зачастую требуется реализовать, по существу, один и тот же метод для разных типов данных.

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

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

Ничто не запрещает вам реализовать несколько перегруженных методов, каждый из которых будет работать совершенно по-разному. Но на практике крайне рекомендуется, чтобы перегруженные методы реализовывали одну и ту же общую операцию.

**Перегрузка конструкторов**

Наряду с перегрузкой обычных методов можно также выполнять перегрузку конструкторов. Перегружаемые конструкторы – это норма и часто используемый прием.

Соответствующий перегружаемый конструктор вызывается в зависимости от параметров, указываемых при выполнении оператора **new**.

```java
class MyClass {
    
    public MyClass() {
        // какой-то код
    }
    
    public MyClass(int arg0) {
        // какой-то код
    }
    
    public MyClass (int arg0, String arg1) {
        // какой-то код
    }
}
```

Если вы пишете для класса несколько конструкторов, иногда бывает удобно вызвать один конструктор из другого, чтобы избежать дублирования кода. Такая операция проводится с использованием ключевого слова **this**.

```java
class MyClass {

    public MyClass() {
        // Вызываем конструктор MyClass(int arg0)
        this(0);
    }

    public MyClass(int arg0) {
        // Вызываем конструктор MyClass (int arg0, String arg1)
        this(arg0, " ");
    }

    public MyClass(int arg0, String arg1) {
        // какой-то код
    }
}
```
