Если я реализую интерфейс, это называется наследование?

31

Если мой класс implements- интерфейс, то могу ли я сказать, что я следую за наследством? Я знаю, что когда класс extendsдругой класс, то это наследование.

RajeeV VenkaT
источник
7
Комментарий Джодрелла просто неверен. Реализация интерфейса - это действительно наследование, а наследование одного интерфейса от другого - наследование. Откуда нам знать? Определив слово, которое мы используем. Наследование - это свойство того, что наследуемые члены одного типа также являются членами другого типа. По этому определению класс, который реализует интерфейс, наследовал все методы интерфейса; просто посмотрите на класс и интерфейс, и вы увидите, что в правильной программе они имеют одинаковых членов.
Эрик Липперт
Я снял галочку и ушел с еще большей растерянностью.
RajeeV VenkaT
18
Что бы это ни стоило, я думаю, вы тратите много времени на определение слова, которое не принесет вам большой пользы. В конце концов, мы все знаем, что означает реализация интерфейса, и считается ли это «наследованием» в значительной степени несущественным для вашей повседневной работы.
Роберт Харви
3
Я (в основном) согласен с Робертом. Я думаю, что есть реальная ценность в понимании точных технических значений жаргонных слов, поскольку они используются в различных контекстах. Но Роберт прав, что гораздо полезнее понимать практическое воздействие! Как вы можете использовать наследование, чтобы сделать ваш код более безопасным? Более тестируемый? Больше многоразового использования? Более гибкий? И так далее. Знание того, что члены базовых типов также являются членами производных типов, - это замечательно, но все же лучше знать, как его эффективно использовать.
Эрик Липперт

Ответы:

78

ОБНОВЛЕНИЕ: я пересмотрел этот ответ. Ряд положительных моментов был поднят в комментариях, которые заслуживают упоминания.

Если мой класс реализует интерфейс, могу ли я сказать, что я следую наследованию?

Не совсем понятно, что вы имеете в виду под «следующим наследованием». Давайте зададим немного другой вопрос?

Что такое наследство?

  • Когда члены одного типа X считаются членами другого типа Y, те члены Y являются унаследованы от X .
  • Существует наследственная связь между некоторыми типами; то есть для некоторых типов X и Y мы говорим «Y наследует от X».

Это немного разные. Это прискорбно, потому что это сбивает с толку.

Какие путаницы обычно возникают из-за этого тонкого различия?

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

Лично я был бы счастлив, если бы в спецификациях Java и C # использовалось слово, отличное от «наследует», для описания взаимосвязи между интерфейсными методами и классами, чтобы избежать этой путаницы. Но они этого не делают, и мы должны исходить из спецификаций, а не против них.

В Java наследуются ли элементы интерфейса классами, которые их реализуют?

Да, некоторые См. Раздел спецификации Java 8.4.8, который я привожу здесь для вашего удобства.

Класс C наследует от своего прямого суперкласса и прямых суперинтерфейсов все абстрактные и стандартные методы m, для которых выполняются все следующие условия: [...]

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

Мы обычно говорим в Java, что класс наследует от интерфейса?

Обычно мы бы сказали, что класс реализует интерфейс. Как отмечено выше, класс может наследовать члены от интерфейса, и все же не сказано, что он наследует от интерфейса. Что сбивает с толку, да.

Имеет ли это тонкое различие значение в повседневной работе?

Обычно нет. Этот вид узкого анализа спецификации более полезен для авторов компиляторов, чем для бизнес-разработчиков. Гораздо важнее понять, когда использовать интерфейс, чем получить точное определение «наследует от».

Эрик Липперт
источник
4
Я не могу спорить с канонической ссылкой. Когда спецификации различаются, как они обязательно делают, простые термины становятся семантически перегруженными и неоднозначными вне контекста. Вопрос помечен, javaтак что это правильный ответ, если ОП не означало что-то другое java:-)
Джодрелл,
5
Хотя вопрос помечен Java, я нахожу проблематичным привести спецификацию языка для общего термина. У многих языков есть интерфейсы, и в их языковых спецификациях может использоваться другой термин, поэтому использование специфичного для Java термина может сбивать с толку при общении с разработчиками, использующими X-Lang.
Томас Оуэнс
5
@ThomasOwens: Я согласен, что этот сценарий распространен, и я полностью не согласен с вашим выводом. Решение проблемы общения, которую вы описываете, состоит в том, чтобы обучить всех вовлеченных лиц точному значению слов в соответствующем контексте . Спецификации существуют для обеспечения этой ясности; используй их!
Эрик Липперт
5
Почему спецификация языка Java получила здесь последнее слово? Спецификация языка часто требует того, с чем «общий разработчик» не согласен в отношении терминологии.
Бенджамин Грюнбаум
5
@BenjaminGruenbaum: Разве я не знаю это. Эти разработчики не правы, и они часто берут на себя обязательство «обучать» других своих неправильных убеждений. Вы не поверите количеству книг по языку программирования, которые мне пришлось исправить, потому что у авторов были совершенно сумасшедшие убеждения относительно VB, C #, JavaScript и т. Д., Которые никоим образом не были правильными. (Джон Скит не был среди них; C # In Depth был верен с самого начала! Никогда я не делал так мало комментариев о книге и все еще получал деньги.)
Эрик Липперт,
26

Наследование означает написание нового подкласса для суперкласса. Написание нового класса для интерфейса реализует этот интерфейс. (А написание нового интерфейса на основе старого расширяет этот интерфейс.)

Единственный правильный термин, который применяется ко всем трем возможностям, это подтип . Не каждый подтип является подклассом.

Килиан Фот
источник
1
В книге GoF, по- видимому, рассматривается наследование интерфейса, подходящий термин для описания подтипирования (Раздел 1.6. Класс и наследование интерфейса)
gnat,
«Однажды я присутствовал на собрании группы пользователей Java, где Джеймс Гослинг (изобретатель Java) был избранным докладчиком. Во время запоминающейся сессии вопросов и ответов кто-то спросил его:« Если бы вы могли сделать Java снова, что бы вы изменили? » пропустите классы ", - ответил он. Он объяснил, что настоящая проблема не в классах как таковых, а в наследовании реализации (отношение extends). Предпочтительным является наследование интерфейса (отношение реализаций). По возможности, следует избегать наследования реализации". javaworld.com/article/2073649/core-java/…
ricardoramos
1

С подклассами вы

  • наследовать состояние суперкласса (все переменные экземпляра, видите ли вы их или нет)
  • наследовать фактические реализации (все неабстрактные методы)

С помощью интерфейсов вы выполняете контракт, реализуя заявленные методы.

Это классический взгляд на это. Теперь с Java 8 интерфейсы становятся смесью:

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

Будет ли реализация интерфейса, все методы которого имеют реализации по умолчанию, по-прежнему считаться «реализацией» или, скорее, расширением? Я не мог сказать. Так как этот случай довольно надуманный (это фактически позволило использовать множественное наследование без сохранения состояния), я бы по-прежнему использовал «наследование» только с подклассами.

Питер Уолсер
источник