абстрактный класс не реализует интерфейс - PullRequest
9 голосов
/ 11 июля 2010

У меня есть интерфейс, поэтому создатели классов вынуждены реализовывать определенные методы.Я также хочу разрешить некоторые реализованные по умолчанию методы, поэтому я создаю абстрактный класс.Проблема в том, что все классы наследуются от базового класса, поэтому у меня есть некоторые вспомогательные функции.

Я попытался написать: IClass с абстрактной базой, но я получил ошибку, что база не реализовалаИнтерфейс.Ну, конечно, потому что я хочу эту аннотацию и чтобы пользователи реализовывали эти методы.В качестве возвращаемого объекта, если я использую базу, я не могу вызвать методы класса интерфейса.Если я использую интерфейс, я не могу получить доступ к базовым методам.

Как мне сделать так, чтобы я мог иметь эти вспомогательные классы и заставлять пользователей реализовывать определенные методы?

Ответы [ 3 ]

15 голосов
/ 11 июля 2010

Убедитесь, что методы в базовом классе имеют то же имя, что и интерфейс, и они общедоступны.Кроме того, сделайте их виртуальными, чтобы подклассы могли переопределять их, не скрывая их.

interface IInterface {
   void Do();
   void Go();
}

abstract class ClassBase : IInterface {

    public virtual void Do() {
         // Default behaviour
    }

    public abstract void Go();  // No default behaviour

}

class ConcreteClass : ClassBase {

    public override void Do() {
         // Specialised behaviour
    }

    public override void Go() {
        // ...
    }

}
6 голосов
/ 11 июля 2010

Переместите методы интерфейса в абстрактный класс и объявите их также абстрактными. Таким образом, производные классы вынуждены их реализовывать. Если вы хотите поведение по умолчанию, используйте абстрактные классы, если вы хотите, чтобы только подпись была исправлена, используйте интерфейс. Обе концепции не смешиваются.

0 голосов
/ 10 марта 2012

Недавно столкнувшись с той же проблемой, я нашел несколько более элегантное (на мой взгляд) решение. Похоже:

public interface IInterface
{
    void CommonMethod();
    void SpecificMethod();
}

public abstract class CommonImpl
{
    public void CommonMethod() // note: it isn't even virtual here!
    {
        Console.WriteLine("CommonImpl.CommonMethod()");
    }
}

public class Concrete : CommonImpl, IInterface
{
    void SpecificMethod()
    {
        Console.WriteLine("Concrete.SpecificMethod()");
    }
}

Теперь, согласно спецификации C # (13.4.4. Отображение интерфейса), в процессе отображения IInterface в классе Concrete компилятор будет искать CommonMethod в CommonImpl, и это не так. даже базовый класс не должен быть виртуальным!

Другое существенное преимущество по сравнению с решением Mau заключается в том, что вам не нужно перечислять каждый элемент интерфейса в абстрактном базовом классе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...