2010-10-05 3 views
5

Можете ли вы определить реализации класса в интерфейсе?Определить класс-реализации в интерфейсе

Например (псевдо-код предупреждения!) ...

interface IClass1 
{ 
    String s { get; set; } 

    // classes implementing this interface has to implement Class2 as "SubClass" 
    Class2 SubClass; 
} 

interface IClass2 
{ 
    Int32 i { get; set; } 
} 

class Class1 : IClass1 
{ 
    String IClass1.s { get; set; } 

    class IClass1.Class2 SubClass 
    { 
     Int32 IClass2.i { get; set; } 
    } 
} 

ответ

4

Целью интерфейса является определение договора, которая отделена от любого реализации.

Что вы можете сделать с интерфейсом определение свойства следующим образом:

interface IClass1 
{ 
    String S { get; set; } 

    Class2 SubClass { get; set; } 
} 
+0

@roosteronacid: Является ли это вашей Предпочтительнее ОТВЕТ? – cseder

3

No. Кроме того, Class2 не подкласс, это вложенный класс или внутренний класс. «Подкласс» (в этом контексте есть другие контексты, которые совершенно разные) другое имя для производного класса, в котором контекстный базовый класс называется «суперклассом» (именно поэтому у Java есть ключевое слово super что аналогично base в C#, хотя и с некоторыми отличиями). «Производные» и «базовые» - это более популярные термины на C#, возможно, потому, что они более популярны в C++, возможно, потому, что Бьярне Страуструп говорит, что он считает их запутанными и даже путается, о чем идет речь (в конце концов, подкласс имеет надмножество поведения и наоборот).

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

2

Синтаксис синтаксиса для принуждения класса к реализации другого вложенного класса. То, что вы эффективно определили здесь, состоит в том, что любая реализация IClass1 должна иметь поле типа Class2.

К сожалению, есть две вещи неправильно с этим:

  1. Class2 не разрешает известного доступного типа, поэтому будет сгенерирована ошибка компиляции.
  2. SubClass член IClass1 объявлен как поле, а интерфейсы не могут объявлять поля.
1

Прежде всего, ваш вопрос: «в состоянии определить класс-реализации в интерфейсе Вы? "

Ответ на этот вопрос: «в пути/нет».
Вы не можете включать определения классов «внутри» определение интерфейса, если это то, что вы имеете в виду.

Как упоминалось ранее, реализация такой вещи может произойти через свойства интерфейса.

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

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

Таким образом, если используется так, как вы хотите, он отходит от концепции C# интерфейсов, но, может быть, кажется, ближе имитировать несколько модель наследования языков, таких как C++ на практике, поскольку он неявно «заставляет всех разработчиков вашего интерфейса создавать экземпляр каждого класса, который имеет интерфейс d свойства для.

Вам нужно немного подумать о причине создания такой структуры (необходимо заставить всех разработчиков интерфейса также создавать экземпляры классов, которые интерфейс определяет как свойства).
Скорее всего, это недостаток дизайна в коде, чем недостающая языковая функция.

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

2

Извинения, если я неправильно понял, но, да, я это сейчас (VB 2013 для .NET 4.0 & 4.5). Интерфейсы могут определять свойства, свойства могут быть сложными, определение класса, для которого может быть вложено в определение интерфейса. В вашем классе, который реализует интерфейс, вы можете использовать только геттер/сеттер для сложного объекта в целом, а не для его индивидуальных свойств. (Геттеры/сеттеры для них, конечно, входят в определение класса). Рабочий пример из VB прилагается вместе с непроверенным преобразованием в C#.

VB:

Interface IPrintable 
    Property Body As DocBody 

    Class DocBody 
     Property Text As String 
     Property FontSize As Single 
    End Class 
End Interface 

Class WordDoc 
    Implements IPrintable 
    Public Property WordBody As IPrintable.DocBody Implements IPrintable.Body 
End Class 

и C#:

interface IPrintable 
{ 
    DocBody Body { get; set; } 
    public class DocBody 
    { 
     public string Text { get; set; } 
     public float FontSize { get; set; } 
    } 
} 

class WordDoc : IPrintable 
{ 
    public IPrintable.DocBody WordBody { get; set; } 
    IPrintable.DocBody IPrintable.Body { 
     get { return WordBody; } 
     set { WordBody = value; } 
    } 
} 
+0

FYI - версия C# не будет компилироваться. C# не допускает классов в интерфейсах. –

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