2010-03-03 3 views
5

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

interface ICommon {...} // Members common to all widgets 
interface IWidget1 {...} // specialized members of widget type 1 
interface IWidget2 {...} // specialized members of widget type 2 

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

interface IWidget1 : ICommon {...} 
interface IWidget2 : ICommon {...} 
class Widget1 : IWidget1 {...} 
class Widget2 : IWidget2 {...} 

... или как это ...

class Widget1: ICommon, IWidget1 {...} 
class Widget2: ICommon, IWidget2 {...} 

Есть ли веская причина, чтобы идти в одну сторону или другую?

Обновление: повлияет ли это на ответ, если классы должны быть COM-видимыми?

ответ

6

Вы должны выбрать наследование интерфейсов тогда и только тогда, когда тип IWidget1 должен иметь значение также реализовать ICommon. В любом случае класс будет реализовывать как IWidget1, так и ICommon отдельно. Единственное различие заключается в том, что если вы сделаете IWidget1 «полученным» из ICommon, вы обеспечите соблюдение того факта, что IWidget1 также должен быть ICommon.

Хорошим примером является IEnumerable и ICollection. Каждому ICollection гарантируется IEnumerable, поэтому ICollection происходит от IEnumerable. Если было законным или имело смысл быть коллекцией, но не было перечислимой, то разработчикам ICollection также не пришлось бы реализовывать IEnumerable.

Какой бы вы ни выбрали, это не повлияет на видимость COM. .NET будет по-прежнему экспортировать интерфейсы отдельно, если я правильно помню.

+0

Правильно, да. Все типы виджетов ДОЛЖНЫ реализовать ICommon. Это причина для этого, чтобы обеспечить его реализацию во всех виджетах. –

+1

Тогда да, конечно, у вас должен быть IWidget1 от ICommon. – Josh

3

Использование принципа Лискова для замены, чтобы помочь вам ответить.

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

+0

Не дает ли тот же результат? –

+0

@ Тим - вы можете уточнить? Я имел в виду, что если вы можете заменить объект IWidget1 для всего кода, ожидающего ICommon1, и имеет смысл иметь объект IWidget1 в вашем домене, то вы можете пойти с наследованием интерфейса. Если нет, то один и тот же класс реализует несколько интерфейсов. – Gishu

+0

OK Я понимаю, что вы имеете в виду. Благодарю. –

0

Наследование зависит от атрибута/поведения класса или интерфейса. Если поведение в IWidget1 и IWidget2 включает все виды поведения в ICommon, то вы наверняка наследуете, как IWidget1 : ICommon и IWidget2 : ICommon, и нет вопросов относительно ComVisible. Это просто концепция OOPS.

1

Существует еще одно соображение, которое, как я думаю, не принималось во внимание в других ответах.

Если вы черпаете IWidgetX из ICommon, а затем придумать виджет, который имеет поведение как IWidget1 и IWidget2 вы можете сделать несколько реализацию интерфейса:

class Widget3 : IWidget1, IWidget2 

Если оба интерфейса были получены из ICommon, то у вас будет две реализации ICommon в вашем классе. Это не большая проблема и может обрабатываться multiple interface implementation, но это изменяет логику.

С другой стороны, если вы не получить IWidgetX от ICommon, вы можете просто реализовать все три, и не должны иметь дело с явной реализации:

class Widget3 : IWidget1, IWidget2, ICommon 

Так что, если это возможно, что вам может понадобиться такой класс Widget3 - вам лучше не выводить интерфейсы IWidgetX из ICommon

+0

+1 спасибо за полезную новую перспективу. –

+0

Спасибо Тиму - хотя оказывается, что я не совсем прав! Я немного углубился в эту идею реализации нескольких интерфейсов, и на самом деле у вас нет двух реализаций ICommon - если бы у вас было, то листинг (ICommon) (новый Widget3()) был бы неразрешимым. Я описал ситуацию более подробно [в этом сообщении блога] (http://stefankiryazov.blogspot.com/2011/09/luke-whos-your-father-multiple.html) Аргумент против получения IWidgetX от ICommon по-прежнему частично – Vroomfundel

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