Если интерфейс наследует два других интерфейса, которые будут иметь одноименные элементы, то должно применяться одно из двух условий:
- Оба интерфейса наследуют один и тот же элемент от какого-то другого интерфейса.Другой интерфейс должен быть общедоступным, но можно задокументировать, что он существует исключительно для наследования, и что от потребителей не требуется объявлять переменные или параметры его типа.
- Интерфейс, который наследует другие интерфейсы, объявляет как `new` свой собственный член с тем же именем.Это хороший подход, когда один интерфейс объявляет свойство только для чтения, а другой объявляет свойство только для записи с тем же именем;Интерфейс, который объединяет эти два интерфейса, может объявлять свойство чтения-записи, реализация которого, как ожидается, будет использовать «getter» свойства только для чтения и «setter» свойства только для записи.Я не уверен, что это будет хорошо во многих других ситуациях.
Если кто-то не делает одну из этих вещей, вероятно, лучше, чтобы компилятор не пытался угадать.Представьте, что у вас есть интерфейсы IListOfDigits
, чей метод Add
добавляет целое число 0-9 к списку, и IBigNumber
, чей метод Add
арифметически добавляет число.Один также имеет интерфейс IListOfDigitsRepresentingBigNumber, который наследует оба.Учитывая, что IListOfDigitsRepresentingBigNumber
называется myThing
и содержит цифры "5,4,3,2", каков должен быть эффект myThing.Add (1)?Должно ли оно изменить myThing
на «5,4,3,2,1» (эффект IListOfDigits.Add
) или «5,4,3,3» (эффект IBigNumber.Add
)?Если кто-то сделает одну из перечисленных выше вещей, компилятору не составит труда выяснить, какой метод Add
использовать.В противном случае, если оба метода могут принять int
, у него не будет подсказки.
Кстати, обобщение и перегрузка представляют интересный случай.Если IFoo<T,U>
имеет члены void Bar(T param)
и void Bar(U param)
, нельзя объявить класс как реализующий IFoo<int,int>
.С другой стороны, можно объявить класс Foo<T,U>
как реализующий IFoo<T,U>
, а затем объявить некоторый другой класс как наследующий от Foo<int,int>
, потому что даже если T
и U
ссылаются на тот же тип, компиляторбудет по-прежнему разрешать перегрузки, используя T
и U
.