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

В чём разница между абстрактным классом и интерфейсом?

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

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

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

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

В чём разница между абстрактным классом и интерфейсом?

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

Ключевые различия

Состояние (State)

Абстрактный класс может содержать поля с состоянием — как приватные, так и защищённые переменные со значениями:

abstract class Animal {
    protected String name;  // состояние
    protected int age;      // состояние
    
    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

Интерфейс в Java (до версии 9) не может содержать состояние. С Java 9 можно добавлять приватные методы, но переменные остаются публичными константами:

interface Swimmer {
    static final int MAX_DEPTH = 100;  // только константы
    // нет полей с состоянием
}

Конструкторы

Абстрактный класс может иметь конструкторы для инициализации:

abstract class Vehicle {
    private String model;
    
    public Vehicle(String model) {
        this.model = model;
    }
    
    abstract void drive();
}

Интерфейс не может иметь конструкторы — инициализацию выполняет класс-реализатор.

Модификаторы доступа

Абстрактный класс поддерживает все модификаторы: public, protected, private, package-private. Это даёт гибкость в скрывании деталей реализации:

abstract class DataProcessor {
    private void validateData() { }      // скрыто
    protected void process() { }         // для наследников
    abstract void execute();             // для всех
}

Интерфейс — все члены публичны (в Java 8+ можно добавить приватные методы).

Множественное наследование

Класс может реализовать несколько интерфейсов, но наследовать только один класс (абстрактный или конкретный):

class Dog extends Animal implements Swimmer, Runner {
    // реализует оба интерфейса
    // наследует только Animal
}

Это избегает проблемы ромба (diamond problem).

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

Абстрактный класс — когда:

  • Нужно разделить логику между несколькими связанными классами
  • Требуется состояние или конструкторы
  • Нужны защищённые члены (приватные переменные)
  • Реализуете является (is-a) отношение: Dog is-a Animal
abstract class DatabaseConnection {
    private String connectionString;
    protected int timeout = 30;
    
    public DatabaseConnection(String connStr) {
        this.connectionString = connStr;
    }
    
    abstract void connect();
    abstract void disconnect();
    
    protected void logQuery(String query) {
        System.out.println("Query: " + query);
    }
}

Интерфейс — когда:

  • Определяете контракт (что должно быть реализовано)
  • Несвязанные классы должны выполнять одинаковые действия
  • Требуется множественное наследование поведения
  • Реализуете может быть (can-do) отношение: Dog can Swim
interface PaymentProcessor {
    void processPayment(double amount);
    void refund(double amount);
    boolean isAvailable();
}

class CreditCardProcessor implements PaymentProcessor {
    @Override
    public void processPayment(double amount) {
        // реализация
    }
    
    @Override
    public void refund(double amount) {
        // реализация
    }
    
    @Override
    public boolean isAvailable() {
        return true;
    }
}

Правило большого пальца

Если выбираете между ними, спросите себя: "Классы связаны иерархией и разделяют общую реализацию?" — абстрактный класс. "Классы просто должны выполнять одинаковый контракт?" — интерфейс.

В современной Java (17+) различия размываются, но философия остаётся: абстрактные классы — для сущностей, интерфейсы — для поведения.

В чём разница между абстрактным классом и интерфейсом? | PrepBro