Ответ
Основное различие заключается в их назначении: абстрактный класс предоставляет базовую реализацию и общий каркас для наследников (отношение is-a
), а интерфейс определяет контракт поведения (набор методов), который класс обязуется выполнить (отношение can-do
).
Детальное сравнение
-
Абстрактный класс:
- Может содержать как абстрактные методы (без реализации), так и обычные методы с реализацией.
- Может иметь состояние (поля, свойства).
- Используется для создания иерархии связанных классов с общим функционалом.
- Класс-наследник расширяет функциональность базового абстрактного класса.
-
Интерфейс:
- Определяет только сигнатуры методов, без их реализации.
- Не может иметь состояния (полей).
- Используется для обеспечения полиморфизма и слабой связности систем.
- Класс может реализовывать несколько интерфейсов, приобретая различные "способности".
Когда что использовать?
- Используйте абстрактный класс, если вы хотите предоставить общую, частично реализованную функциональность для группы тесно связанных классов.
- Используйте интерфейс, если вам нужно определить контракт для классов, которые могут быть не связаны друг с другом, но должны выполнять определенное действие (например,
Serializable
,Sortable
).
Пример на Python
В Python нет формального ключевого слова interface
, но эта концепция реализуется с помощью абстрактных базовых классов (abc
).
from abc import ABC, abstractmethod
# Интерфейс определяет "что делать" (контракт)
class Flyable(ABC):
@abstractmethod
def fly(self):
pass
# Абстрактный класс определяет "кем быть" и может содержать реализацию
class Animal(ABC):
def __init__(self, name):
self.name = name
@abstractmethod
def make_sound(self):
pass
def sleep(self):
print(f"{self.name} is sleeping... Zzz")
# Класс реализует интерфейс и наследует абстрактный класс
class Bird(Animal, Flyable):
def make_sound(self):
print("Chirp!")
def fly(self):
print(f"{self.name} is flying high")
bird = Bird("Sparrow")
bird.make_sound() # Chirp!
bird.fly() # Sparrow is flying high
bird.sleep() # Sparrow is sleeping... Zzz