2010-07-11 3 views
8

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

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

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

ответ

6

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

15

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

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() { 
     // ... 
    } 

} 
0

Столкнувшись с той же проблемой в последнее время, я придумал несколько более изящное (на мой взгляд) решение. Это выглядит следующим образом:

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 тоже, и это Безразлично» t даже должен быть виртуальным в базовом классе!

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

+0

Я предпочитаю решение Мау. Он явственен и делает компилятор выполненным для вас. В этом решении вы можете забыть добавить IInterface к производному классу. – PlayTank

+0

@PlayTank: ... и затем, в конце концов, он будет терпеть неудачу при некотором неявном преобразовании, также во время компиляции. Хотя я согласен, что в решении отсутствует определенная строгость. – vines

Смежные вопросы