Se eu implementar uma interface, isso é chamado de herança?

31

Se minha classe é implementsuma interface, posso dizer que estou seguindo a herança? Eu sei que quando uma classe é extendsoutra, então é herança.

RajeeV VenkaT
fonte
7
O comentário de Jodrell está simplesmente errado. Implementar uma interface é realmente herança, e herdar uma interface de outra é herança. Como nós sabemos? Definindo a palavra que estamos usando. Herança é a propriedade que os membros herdáveis ​​de um tipo também são membros de outro tipo. Por essa definição, claramente uma classe que implementa uma interface herdou todos os métodos da interface; basta olhar para a classe e a interface e você descobrirá que em um programa correto, eles têm os mesmos membros.
precisa
Desmarquei e parti com mais confusão.
Rajeev Venkat
18
Pelo que vale, acho que você está gastando muito tempo em uma definição de palavra que não trará muitos benefícios a você. No final do dia, todos sabemos o que significa implementar uma interface e se ela é considerada "herança" é em grande parte irrelevante para o seu trabalho diário.
31716 Robert Harvey
3
Eu (principalmente) concordo com Robert. Eu acho que existe um valor real na compreensão dos significados técnicos precisos das palavras de jargão, pois elas são usadas em vários contextos. Mas Robert está certo de que é de um benefício muito maior entender o impacto prático! Como você pode usar a herança para tornar seu código mais seguro? Mais testável? Mais reutilizável? Mais flexível? E assim por diante. Saber que membros de tipos de base também são membros de tipos derivados é ótimo, mas é melhor saber como usá-lo efetivamente.
precisa

Respostas:

78

ATUALIZAÇÃO: Revisei esta resposta. Vários pontos positivos foram levantados nos comentários que mereciam ser destacados.

Se minha classe implementa uma interface, posso dizer que estou seguindo a herança?

Não está totalmente claro o que você quer dizer com "seguindo herança". Vamos fazer uma pergunta um pouco diferente?

O que é herança?

  • Quando os membros de um tipo X são considerados como sendo membros de outro tipo Y, os membros de Y são herdados a partir de X .
  • Há um relacionamento de herança entre alguns tipos; isto é, para alguns tipos X e Y, dizemos "Y herda de X".

Estes são sutilmente diferentes. Isso é lamentável, porque é confuso.

Que confusões normalmente surgem dessa distinção sutil?

A confusão pode surgir porque as pessoas pensam na herança como um mecanismo para compartilhar detalhes de implementação. Embora seja esse mecanismo, esse mecanismo funciona compartilhando membros . Esses membros não precisam ter implementações! Como veremos, eles podem ser abstratos.

Pessoalmente, ficaria mais feliz se as especificações Java e C # usassem uma palavra diferente de "herda" para descrever o relacionamento entre métodos e classes de interface, para evitar essa confusão. Mas eles não o fazem, e temos que argumentar com base nas especificações, não contra elas.

Em Java, os membros da interface são herdados pelas classes que os implementam?

Sim, alguns são. Veja a seção 8.4.8 da especificação Java, que cito aqui para sua conveniência.

Uma classe C herda de sua superclasse direta e superinterfaces diretas todos os métodos abstratos e padrão m para os quais todos os seguintes são verdadeiros: [...]

Se você diz que uma classe implementa uma interface, a classe herda os métodos abstrato e padrão dessa interface . (É claro que omiti as condições a seguir; consulte a especificação para obter detalhes. Em particular, uma classe que implementa um membro de uma interface não é considerada como tendo herdado esse membro. Novamente, isso é confuso? Sim.)

Normalmente dizemos em Java que uma classe herda de uma interface?

Normalmente, diríamos que uma classe implementa uma interface. Como observado acima, uma classe pode herdar membros de uma interface e ainda assim não é dito que ela herdou da interface. O que é confuso, sim.

Essa distinção sutil importa no trabalho do dia a dia?

Normalmente não. Esse tipo de análise restrita da especificação é mais útil para escritores de compiladores do que para desenvolvedores de linha de negócios. É mais importante entender quando usar uma interface do que obter uma definição precisa de "herda de".

Eric Lippert
fonte
4
Não posso argumentar com uma referência canônica. Quando as especificações diferem, como necessariamente fazem, termos simples tornam-se semanticamente sobrecarregados e ambíguos fora de contexto. A questão é marcado com javaisso esta é a resposta certa, a menos que o OP significava alguma outra java:-)
Jodrell
5
Embora a pergunta esteja marcada com Java, acho problemático citar uma especificação de linguagem para um termo genérico. Muitas linguagens possuem interfaces e suas especificações de linguagem podem usar um termo diferente; portanto, o uso de um termo específico de Java pode ser confuso ao conversar com desenvolvedores que usam o X-Lang.
Thomas Owens
5
@ ThomasOwens: Concordo que esse cenário é comum e discordo completamente de sua conclusão. A solução para o problema de comunicação que você descreve é educar todos os envolvidos quanto aos significados precisos das palavras no contexto relevante . Existem especificações para fornecer essa clareza; usa-os!
31516 Eric
5
Por que a especificação da linguagem Java teria a palavra final aqui? A especificação de linguagem geralmente afirma coisas que o "desenvolvedor comum" discorda sobre terminologia.
Benjamin Gruenbaum
5
@BenjaminGruenbaum: Eu não sei. Esses desenvolvedores estão errados e costumam "educar" os outros sobre suas crenças erradas. Você não acreditaria no número de livros sobre linguagens de programação que tive que corrigir, porque os autores tinham algumas crenças completamente loucas sobre VB, C #, JavaScript etc. que não eram de forma alguma corretas. (Jon Skeet não estava entre eles; C # In Depth estava correto desde o início Eu nunca fez tão poucos comentários sobre um livro e ainda começado pago!.)
Eric Lippert
26

Herança significa escrever uma nova subclasse para uma superclasse. Escrever uma nova classe em uma interface está implementando essa interface. (E escrever uma nova interface com base em uma antiga está estendendo essa interface.)

O único termo correto que se aplica a todas as três possibilidades é subtipagem . Nem todo subtipo é uma subclasse.

Kilian Foth
fonte
11
GoF livro parecem considerar herança de interface termo apropriado para descrever subtipagem (Seção 1.6 Classe contra Interface de Herança)
mosquito
"Certa vez, participei de uma reunião do grupo de usuários Java em que James Gosling (inventor do Java) foi o orador em destaque. Durante a memorável sessão de perguntas e respostas, alguém perguntou a ele:" Se você pudesse fazer o Java novamente, o que mudaria? " deixe de fora as classes ", respondeu ele. Ele explicou que o problema real não eram as classes em si, mas a herança da implementação (o relacionamento estendido). A herança da interface (o relacionamento dos implementos) é preferível. Você deve evitar a herança da implementação sempre que possível." javaworld.com/article/2073649/core-java/…
ricardoramos
1

Com subclasses , você

  • estado de herança da superclasse (todas as variáveis ​​de instância, quer você as veja ou não)
  • herdar implementações reais (todos os métodos não abstratos)

Com interfaces , você preenche um contrato implementando os métodos declarados.

Essa é a maneira clássica de ver isso. Agora, com o Java 8, as interfaces se tornam uma mistura:

  • você ainda não herda o estado (como as interfaces ainda não têm variáveis ​​de instância)
  • agora você pode herdar implementações padrão da interface

A implementação de uma interface cujos métodos todos têm implementações padrão ainda conta como 'implementar', ou melhor, como extensão? Eu não sabia dizer. Como esse caso é exagerado (isso realmente habilitou a herança múltipla sem estado), eu ainda usaria 'herança' apenas nas subclasses.

Peter Walser
fonte