Как ответить
Основное отличие в том, что интерфейс задаёт контракт (что должно быть), а абстрактный класс — частичную реализацию (что уже есть + что нужно доделать). В Java и C# это закреплено синтаксически: класс может реализовать много интерфейсов, но унаследовать только один абстрактный класс.
На практике это выглядит так:
- Интерфейс — только сигнатуры методов (до Java 8). Пример:
Comparableтребует методcompareTo(), но не даёт готового кода. Если два класса реализуют один интерфейс, их можно использовать полиморфно через общий тип. - Абстрактный класс — может содержать поля, конструкторы, реализованные методы. Например,
AbstractListв Java уже реализуетadd()иremove()черезget()иsize(), оставляя только их абстрактными. Наследник пишет только специфику.
Ключевые различия:
- Наследование: интерфейсов — множественное, абстрактных классов — одиночное.
- Состояние: в интерфейсе нет полей (только константы), в абстрактном классе — любые поля.
- Конструкторы: у интерфейса их нет, у абстрактного класса — есть.
- Модификаторы доступа: в интерфейсе методы
publicпо умолчанию, в абстрактном классе — любые.
Пример кода на Java:
// Интерфейс — только контракт
public interface Drawable {
void draw();
}
// Абстрактный класс — частичная реализация
public abstract class Shape {
protected int x, y;
public Shape(int x, int y) {
this.x = x;
this.y = y;
}
public void move(int dx, int dy) {
x += dx;
y += dy;
}
public abstract double area();
}
// Конкретный класс
public class Circle extends Shape implements Drawable {
private int radius;
public Circle(int x, int y, int radius) {
super(x, y);
this.radius = radius;
}
@Override
public double area() {
return Math.PI * radius * radius;
}
@Override
public void draw() {
System.out.println("Рисую круг в (" + x + "," + y + ")");
}
}Когда что выбирать:
- Интерфейс — если нужно описать поведение, которое может быть у разных несвязанных классов (например,
Serializable,Runnable). - Абстрактный класс — если классы логически связаны и имеют общую базу (например, разные виды животных с общими полями и методами).
В современных языках (Java 8+, C# 8+) интерфейсы получили default-методы, что немного размыло границу, но концептуально разница остаётся: интерфейс — это способность (can do), абстрактный класс — сущность (is a).