Наследование нескольких интерфейсов - PullRequest
5 голосов
/ 03 марта 2010

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

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?

Ответы [ 4 ]

6 голосов
/ 03 марта 2010

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

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

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

3 голосов
/ 03 марта 2010

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

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

1 голос
/ 20 сентября 2011

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

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

class Widget3 : IWidget1, IWidget2

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

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

class Widget3 : IWidget1, IWidget2, ICommon

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

0 голосов
/ 03 марта 2010

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

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