Інтерфейс - це лише контракт: перелік публічних методів, які клас зобов'язується мати. Реалізації в ньому немає (крім констант), і клас може реалізувати скільки завгодно інтерфейсів.
Абстрактний клас - це недобудований клас: у ньому можуть бути властивості, готові методи й абстрактні методи, які мають дописати нащадки. Успадкувати можна лише один клас.
interface PaymentGateway
{
public function charge(Money $amount): Receipt;
}
abstract class HttpGateway implements PaymentGateway
{
public function __construct(protected HttpClient $http) {}
protected function post(string $path, array $data): array
{
return $this->http->post($this->baseUrl() . $path, $data);
}
abstract protected function baseUrl(): string;
}
Коли що:
- Інтерфейс - коли потрібна взаємозамінність: код залежить від
PaymentGateway, а конкретний шлюз підставляється ззовні. - Абстрактний клас - коли кілька реалізацій ділять спільний код і стан.
Часто вони йдуть разом, як у прикладі: залежать від інтерфейсу, а абстрактний клас лише прибирає повтор між реалізаціями.