Возможно, станет понятнее, если вы будете думать о методах получения и установки как о методах, которыми они в конечном итоге станут.
В случае интерфейса вы определяете это:
interface IFoo
{
string GetBar();
}
Какиеможет читаться как «все классы, которые реализуют этот интерфейс , должны включать этот метод».Оба ваших класса делают:
class RealFoo : IFoo
{
public string GetBar();
private void SetBar(string value);
}
они также реализуют SetBar (), но это несущественно;они выполнили контракт, определенный интерфейсом, и являются действительными.
С другой стороны, абстрактный класс выглядит так:
abstract class AbstractFoo : IFoo
{
public abstract string GetBar();
}
Это означает, что все дочерние классы должны предоставлять тело методадля GetBar ()
Созданный вами класс выглядит следующим образом:
class RealFoo : AbstractFoo
{
public override string GetBar();
public override void SetBar(string value);
}
Поместив модификатор override перед методом SetBar, компилятор ожидает найти абстрактную или виртуальную версию вБазовый класс.У вас его нет, поэтому компиляция не удалась.