Комментарии (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;
}
}
Сравнительная таблица
| Аспект | this | super |
|---|---|---|
| Указывает на | Текущий объект | Родительский класс |
| Для доступа к | Полям/методам текущего класса | Полям/методам родительского класса |
| Для Constructor Chaining | this() - другому конструктору текущего класса | 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.