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

В чем разница между this и super?

1.0 Junior🔥 171 комментариев
#Основы Java

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

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

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

Разница между this и super в Java

Это фундаментальные концепции наследования и полиморфизма. Давайте разберемся.

Что такое this

this - ссылка на текущий объект (объект класса, в котором используется this).

public class User {
    private String name;
    private String email;
    
    public User(String name, String email) {
        this.name = name;      // this.name указывает на поле текущего объекта
        this.email = email;
    }
    
    public void printInfo() {
        System.out.println(this.name);  // this.name - имя текущего объекта
    }
    
    public void setName(String name) {
        this.name = name;  // Локальная переменная 'name' отличается от поля 'this.name'
    }
}

User user = new User("John", "john@example.com");
user.printInfo();  // this в printInfo() указывает на user

Применение this

1. Обращение к полям и методам текущего объекта

public class Car {
    private String brand;
    private String model;
    private int year;
    
    public Car(String brand, String model, int year) {
        this.brand = brand;   // Избегаем путаницы с параметром
        this.model = model;
        this.year = year;
    }
    
    public void displayInfo() {
        System.out.println("Brand: " + this.brand);
        System.out.println("Model: " + this.model);
        System.out.println("Year: " + this.year);
        this.honk();  // Вызов метода текущего объекта
    }
    
    private void honk() {
        System.out.println("Beep beep!");
    }
}

2. Constructor Chaining (передача управления другому конструктору)

public class Employee {
    private String id;
    private String name;
    private String department;
    private double salary;
    
    // Конструктор 1 - минимальный
    public Employee(String name) {
        this(name, null);  // Вызываем другой конструктор через this()
    }
    
    // Конструктор 2 - с department
    public Employee(String name, String department) {
        this(name, department, 0.0);  // Передаем управление конструктору 3
    }
    
    // Конструктор 3 - полный
    public Employee(String name, String department, double salary) {
        this.id = UUID.randomUUID().toString();
        this.name = name;
        this.department = department;
        this.salary = salary;
    }
}

Employee emp1 = new Employee("John");  // Вызывает конструктор 1
// -> this("John", null) -> вызывает конструктор 2
// -> this("John", null, 0.0) -> вызывает конструктор 3

3. Возврат текущего объекта (Fluent Interface / Builder pattern)

public class Person {
    private String firstName;
    private String lastName;
    private int age;
    
    public Person setFirstName(String firstName) {
        this.firstName = firstName;
        return this;  // Возвращаем текущий объект
    }
    
    public Person setLastName(String lastName) {
        this.lastName = lastName;
        return this;
    }
    
    public Person setAge(int age) {
        this.age = age;
        return this;
    }
}

// Использование: Method Chaining
Person person = new Person()
    .setFirstName("John")
    .setLastName("Doe")
    .setAge(30);

Что такое super

super - ссылка на родительский класс (superclass). Используется для доступа к методам и полям родительского класса.

public class Animal {
    protected String name;
    
    public void makeSound() {
        System.out.println("Some sound");
    }
}

public class Dog extends Animal {
    @Override
    public void makeSound() {
        super.makeSound();  // Вызываем метод родительского класса
        System.out.println("Woof!");
    }
    
    public void setName(String name) {
        this.name = name;  // Доступ к полю родительского класса
    }
}

Dog dog = new Dog();
dog.makeSound();
// Вывод:
// Some sound
// Woof!

Применение super

1. Вызов метода родительского класса

public class Vehicle {
    public void start() {
        System.out.println("Vehicle is starting...");
    }
}

public class Car extends Vehicle {
    @Override
    public void start() {
        super.start();  // Вызываем реализацию из Vehicle
        System.out.println("Car engine starting...");
    }
}

// Использование
Car car = new Car();
car.start();
// Вывод:
// Vehicle is starting...
// Car engine starting...

2. Вызов конструктора родительского класса

public class Person {
    protected String name;
    protected int age;
    
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("Person created: " + name);
    }
}

public class Employee extends Person {
    private String employeeId;
    private double salary;
    
    public Employee(String name, int age, String employeeId, double salary) {
        super(name, age);  // Вызываем конструктор родителя
        this.employeeId = employeeId;
        this.salary = salary;
        System.out.println("Employee created with ID: " + employeeId);
    }
}

Employee emp = new Employee("John", 30, "EMP001", 50000);
// Вывод:
// Person created: John
// Employee created with ID: EMP001

Важно: Вызов super() должен быть ПЕРВОЙ строкой в конструкторе!

3. Доступ к переопределенным методам

public class Shape {
    public void draw() {
        System.out.println("Drawing a shape");
    }
    
    public double getArea() {
        return 0;
    }
}

public class Circle extends Shape {
    private double radius;
    
    public Circle(double radius) {
        this.radius = radius;
    }
    
    @Override
    public void draw() {
        super.draw();  // Вызовем базовую реализацию
        System.out.println("Drawing a circle with radius: " + radius);
    }
    
    @Override
    public double getArea() {
        return Math.PI * radius * radius;
    }
}

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

Аспектthissuper
Указывает наТекущий объектРодительский класс
Для доступа кПолям/методам текущего классаПолям/методам родительского класса
Для Constructor Chainingthis() - другому конструктору текущего классаsuper() - конструктору родительского класса
Возврат объектаМожет возвращать thisНе может возвращаться
Когда использоватьВсегда в текущем классеКогда переопределяешь метод/конструктор

Практический пример: Иерархия классов

// Базовый класс
public abstract class BankAccount {
    protected String accountNumber;
    protected double balance;
    
    public BankAccount(String accountNumber, double initialBalance) {
        this.accountNumber = accountNumber;
        this.balance = initialBalance;
    }
    
    public void withdraw(double amount) {
        if (amount <= balance) {
            balance -= amount;
            System.out.println("Withdrawn: " + amount);
        }
    }
}

// Класс-наследник
public class SavingsAccount extends BankAccount {
    private double interestRate;
    
    public SavingsAccount(String accountNumber, double initialBalance, double interestRate) {
        super(accountNumber, initialBalance);  // Вызываем конструктор родителя
        this.interestRate = interestRate;
    }
    
    @Override
    public void withdraw(double amount) {
        if (amount > balance * 0.8) {  // Не можем снять больше 80%
            System.out.println("Cannot withdraw more than 80% of balance");
            return;
        }
        super.withdraw(amount);  // Вызываем базовую реализацию
    }
    
    public void addInterest() {
        balance = balance * (1 + interestRate);
        System.out.println("Interest added. New balance: " + balance);
    }
}

public class CheckingAccount extends BankAccount {
    private int transactionLimit;
    private int transactionsUsed;
    
    public CheckingAccount(String accountNumber, double initialBalance, int transactionLimit) {
        super(accountNumber, initialBalance);
        this.transactionLimit = transactionLimit;
        this.transactionsUsed = 0;
    }
    
    @Override
    public void withdraw(double amount) {
        if (transactionsUsed >= transactionLimit) {
            System.out.println("Transaction limit exceeded");
            return;
        }
        super.withdraw(amount);
        transactionsUsed++;
    }
}

// Использование
SavingsAccount savings = new SavingsAccount("SA001", 10000, 0.05);
savings.withdraw(5000);  // OK
savings.withdraw(9000);  // Ошибка - больше 80%
savings.addInterest();

CheckingAccount checking = new CheckingAccount("CA001", 5000, 5);
for (int i = 0; i < 6; i++) {
    checking.withdraw(100);  // После 5-го вызова будет ошибка
}

Распространенные ошибки

// ✗ Ошибка 1: Забыли super() в конструкторе
public class Child extends Parent {
    public Child(String name) {
        // Где-то неявно вызывается super(), но если Parent не имеет default конструктора
        // это вызовет ошибку компиляции
    }
}

// ✓ Правильно
public class Child extends Parent {
    public Child(String name) {
        super(name);  // Явно вызываем конструктор родителя
    }
}

// ✗ Ошибка 2: Путаница с this() и super()
public class Wrong extends Parent {
    public Wrong(String name) {
        super(name);  // Правильно - вызов родителя
    }
    
    public void method() {
        this("test");  // ОШИБКА - нельзя вызвать конструктор из метода!
    }
}

// ✓ Правильное использование this()
public class Correct {
    public Correct() {
        this("default");  // Вызов другого конструктора - только из конструктора!
    }
    
    public Correct(String name) {
        // инициализация
    }
}

Резюме

  • this - ссылка на ТЕКУЩИЙ объект

    • Используется для обращения к полям и методам своего класса
    • Constructor Chaining: this()
    • Возврат текущего объекта для fluent interface
  • super - ссылка на РОДИТЕЛЬСКИЙ класс

    • Используется при переопределении методов
    • Вызов конструктора родителя: super()
    • Доступ к скрытым полям/методам родителя

Понимание разницы - основа наследования и полиморфизма в Java.