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

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

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

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

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

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

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

Переменагрузка методов (method overloading) — это возможность определить несколько методов с одним именем, но разными параметрами. Это классическая концепция в объектно-ориентированном программировании, особенно в языках с静态ой типизацией.

Концепция

Методы различаются по:

  • Количеству параметров
  • Типам параметров
  • Порядку параметров

Арумент (сигнатура метода) определяет, какой метод будет вызван.

// Java пример (классический)
public class Calculator {
  public int add(int a, int b) {
    return a + b;
  }
  
  public double add(double a, double b) {
    return a + b;
  }
  
  public int add(int a, int b, int c) {
    return a + b + c;
  }
}

Calculator calc = new Calculator();
calc.add(1, 2);           // Вызовет int add(int, int)
calc.add(1.5, 2.5);       // Вызовет double add(double, double)
calc.add(1, 2, 3);        // Вызовет int add(int, int, int)

Перегрузка в JavaScript/TypeScript

JavaScript не поддерживает истинную перегрузку — последний метод с тем же именем перезапишет предыдущий.

// JavaScript — перезапись
function add(a, b) {
  return a + b;
}

function add(a, b, c) {  // Перезаписывает предыдущую функцию
  return a + b + c;
}

add(1, 2);     // Вернёт undefined (c отсутствует)
add(1, 2, 3);  // Вернёт 6

Эмуляция перегрузки в TypeScript:

// Function overloading declarations
function add(a: number, b: number): number;
function add(a: string, b: string): string;
function add(a: number, b: number, c: number): number;

// Implementation
function add(a: any, b: any, c?: any): any {
  if (typeof a === 'string' && typeof b === 'string') {
    return a + b;  // Конкатенация
  }
  if (c !== undefined) {
    return a + b + c;
  }
  return a + b;
}

add(1, 2);        // number
add('a', 'b');    // string
add(1, 2, 3);     // number

Альтернативные подходы в JavaScript

1. Проверка параметров:

function process(input) {
  if (typeof input === 'string') {
    return input.toUpperCase();
  }
  if (Array.isArray(input)) {
    return input.length;
  }
  if (typeof input === 'object') {
    return Object.keys(input).length;
  }
}

process('hello');       // HELLO
process([1, 2, 3]);     // 3
process({a: 1, b: 2});  // 2

2. Rest параметры:

function sum(...numbers: number[]): number {
  return numbers.reduce((a, b) => a + b, 0);
}

sum(1);           // 1
sum(1, 2);        // 3
sum(1, 2, 3, 4);  // 10

3. Опциональные и default параметры:

function greet(name: string, greeting?: string, exclamation: boolean = true) {
  const punctuation = exclamation ? '!' : '.';
  const msg = greeting || 'Hello';
  return `${msg}, ${name}${punctuation}`;
}

greet('John');                    // Hello, John!
greet('John', 'Hi');              // Hi, John!
greet('John', 'Hi', false);       // Hi, John.

4. Объект параметров (object destructuring):

interface QueryOptions {
  page?: number;
  limit?: number;
  sort?: string;
  filter?: string;
}

function query(options: QueryOptions) {
  const {
    page = 1,
    limit = 10,
    sort = 'date',
    filter
  } = options;
  
  return {page, limit, sort, filter};
}

query({});                                    // defaults
query({page: 2});                             // page=2, other defaults
query({limit: 50, sort: 'name'});            // custom

Перегрузка в классах

class FileHandler {
  // Перегрузка сигнатур
  read(path: string): Promise<string>;
  read(path: string, encoding: string): Promise<string>;
  read(path: string, options: {encoding: string; cache: boolean}): Promise<string>;
  
  // Реализация
  async read(path: string, encodingOrOptions?: any): Promise<string> {
    let encoding = 'utf-8';
    let useCache = false;
    
    if (typeof encodingOrOptions === 'string') {
      encoding = encodingOrOptions;
    } else if (typeof encodingOrOptions === 'object') {
      encoding = encodingOrOptions.encoding;
      useCache = encodingOrOptions.cache;
    }
    
    if (useCache) {
      // check cache
    }
    
    return await fs.promises.readFile(path, encoding);
  }
}

const handler = new FileHandler();
await handler.read('file.txt');
await handler.read('file.txt', 'utf-8');
await handler.read('file.txt', {encoding: 'utf-8', cache: true});

Когда использовать

Перегрузка полезна когда:

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

Избегай перегрузки когда:

  • Логика существенно отличается (разбей на разные методы)
  • Количество вариантов растёт экспоненциально
  • Усложняется читаемость кода

Best practices

  1. Сначала специфичные, потом общие:
function process(input: string): string;       // Специфичная
function process(input: any[]): number;        // Специфичная
function process(input: any): any;             // Общая
  1. Минимизируй перегрузку:
// Bad: слишком много вариантов
function query(a?, b?, c?, d?, e?, f?) {}

// Good: объект параметров
function query(options: QueryOptions) {}
  1. Документируй каждую сигнатуру:
/**
 * Читает файл
 * @param path - путь к файлу
 * @returns содержимое файла
 */
function read(path: string): Promise<string>;

/**
 * Читает файл с кодировкой
 * @param path - путь к файлу
 * @param encoding - кодировка (utf-8, ascii и т.д.)
 */
function read(path: string, encoding: string): Promise<string>;

Вывод: Перегрузка методов в TypeScript — это удобный способ предоставить гибкий API с сохранением типобезопасности. Но в JavaScript без типизации лучше использовать объекты параметров и rest параметры для большей гибкости и читаемости.