Я думаю, что ключевая концепция, которую вам не хватает, - это разница между наследованием и реализацией интерфейса.
Когда класс наследует другой класс, это означает, что это в основном более специфический тип базового класса - например,собака - это особый тип животного, поэтому, когда у вас есть такие классы, как:
class Animal {/* implementation here */}
class Dog : Animal {/* dog implementation here */}
Класс Dog
уже содержит все реализации Animal, кроме его конструкторов (статических и экземпляров) иФинализаторы.
Однако, когда класс реализует интерфейс, это означает, что он должен предоставлять члены указанного интерфейса (а именно метод, свойства, события и индексаторы), поэтому, если у вас есть интерфейс IAnimal
иКласс Dog
, реализующий его напрямую, ваш код выглядит следующим образом:
interface IAnimal
{
void Eat();
}
class Dog : IAnimal
{
public void Eat() {/* implementation here */}
}
Обратите внимание, что все, что объявляет IAnimal
, должно быть реализовано, явно или неявно, в классе Dog
, поэтомуКонтракт, предоставленный интерфейсом, сохраняется в классе - независимо от того, является ли пользовательlass знает интерфейс или нет.
Итак, в заключение - чтобы использовать класс, вам не нужно ничего знать об интерфейсах, которые он реализует, но вам нужно знать все, что является классом, и посколькуСобака - это животное, если собака общедоступна, то же самое должно быть и с животным.
Интерфейс IAnimal, с другой стороны, может оставаться внутренним.
Еще один момент о реализации внутренних интерфейсов, уже упомянутый вкомментарии к вопросу от пользователя 2864740 - Поскольку все неявные реализации интерфейса должны быть открытыми - если вы реализуете внутренний интерфейс, вам следует рассмотреть возможность явной его реализации - таким образом, реализация остается внутренней и не раскрывается вневмещающий узел.