---
title: "Подъём тела конструктора"
type: "refactoring-technique"
slug: "pull-up-constructor-body"
url: "http://localhost:3000/ru/pull-up-constructor-body.md"
category: "Решение задач обобщения"
description: "Проблема: Подклассы имеют конструкторы с преимущественно одинаковым кодом. Решение: Создайте конструктор в суперклассе и вынесите в него общий для подклассов код. Вызывайте конструктор суперкласса в конструкторах подкласса."
languages: ["java", "csharp", "php", "python", "typescript"]
---
# Подъём тела конструктора

> Проблема: Подклассы имеют конструкторы с преимущественно одинаковым кодом. Решение: Создайте конструктор в суперклассе и вынесите в него общий для подклассов код. Вызывайте конструктор суперкласса в конструкторах подкласса.

## Problem

Подклассы имеют конструкторы с преимущественно одинаковым кодом.

## Solution

Создайте конструктор в суперклассе и вынесите в него общий для подклассов код. Вызывайте конструктор суперкласса в конструкторах подкласса.

## Why Refactor

Чем этот рефакторинг отличается от [подъёма метода](/ru/pull-up-method)?

1. В Java подклассы не могут наследовать конструктор, поэтому вы не можете просто применить [подъём метода](/ru/pull-up-method) к конструктору подкласса и удалить его после перемещения всего кода конструктора в суперкласс. Вдобавок к созданию конструктора в суперклассе нужно будет иметь конструкторы в подклассах с простым делегированием к конструктору суперкласса.
2. В C++ и Java (в случае, если вы явно не вызвали конструктор суперкласса) конструктор суперкласса автоматически вызывается перед конструктором подкласса, что делает обязательным перемещение общего кода только из начала конструкторов подклассов (так как вы не сможете вызвать конструктор суперкласса в произвольном месте конструктора подкласса).
3. В большинстве языков программирования конструктор подкласса может иметь свой собственный список параметров, отличный от параметров суперкласса, поэтому вы должны создать конструктор суперкласса только с теми параметрами, которые ему действительно нужны.

## How to Refactor

1. Создайте конструктор в суперклассе.
2. Извлеките общий код из начала конструктора каждого из подклассов в конструктор суперкласса. Перед этим действием стоит попробовать поместить как можно больше общего кода в начало конструктора.
3. Поместите вызов конструктора суперкласса первой строкой в конструкторах подклассов.
## Relations

**Similar techniques**

- [Подъём метода](/ru/pull-up-method.md)

**Eliminates smells**

- [Дублирование кода](/ru/smells/duplicate-code.md)

## Code Examples

### java

```java
// Before
class Manager extends Employee {
  public Manager(String name, String id, int grade) {
    this.name = name;
    this.id = id;
    this.grade = grade;
  }
  // ...
}

// After
class Manager extends Employee {
  public Manager(String name, String id, int grade) {
    super(name, id);
    this.grade = grade;
  }
  // ...
}
```

### csharp

```csharp
// Before
public class Manager: Employee 
{
  public Manager(string name, string id, int grade) 
  {
    this.name = name;
    this.id = id;
    this.grade = grade;
  }
  // ...
}

// After
public class Manager: Employee 
{
  public Manager(string name, string id, int grade): base(name, id)
  {
    this.grade = grade;
  }
  // ...
}
```

### php

```php
// Before
class Manager extends Employee {
  public function __construct($name, $id, $grade) {
    $this->name = $name;
    $this->id = $id;
    $this->grade = $grade;
  }
  // ...
}

// After
class Manager extends Employee {
  public function __construct($name, $id, $grade) {
    parent::__construct($name, $id);
    $this->grade = $grade;
  }
  // ...
}
```

### python

```python
// Before
class Manager(Employee):
    def __init__(self, name, id, grade):
        self.name = name
        self.id = id
        self.grade = grade
    # ...

// After
class Manager(Employee):
    def __init__(self, name, id, grade):
        Employee.__init__(name, id)
        self.grade = grade
    # ...
```

### typescript

```typescript
// Before
class Manager extends Employee {
  constructor(name: string, id: string, grade: number) {
    this.name = name;
    this.id = id;
    this.grade = grade;
  }
  // ...
}

// After
class Manager extends Employee {
  constructor(name: string, id: string, grade: number) {
    super(name, id);
    this.grade = grade;
  }
  // ...
}
```

