Абстрактные классы могут предоставлять реализации для своих методов, тогда как Интерфейс строго предоставляет контракт (какие методы должен реализовывать объект).
Абстрактные классы полезны в ситуациях, когда вы хотите предоставить базовую реализацию наследникам, но вы не хотите, чтобы экземпляр вашего класса создавался напрямую. Например, подумайте об автомобиле. Вы не хотели бы создавать универсальный автомобиль, но каждая забота может иметь некоторый базовый набор функций:
public abstract class Car
{
public InternalCombustionEngine Engine { get; private set; }
public virtual void Start()
{
Engine.Start();
}
public abstract void Drive();
}
Интерфейсы полезны, когда у вас есть некоторые классы, которые могут не иметь прямого отношения друг к другу, но вы хотите обрабатывать их одинаково, потому что у каждого из них одинаковый набор функций.