O Java 8 permite a implementação padrão de métodos em interfaces chamadas Métodos Padrão .
Estou confuso entre quando eu usaria esse tipo de interface default method
, em vez de um abstract class
(com abstract method(s)
).
Então, quando a interface com os métodos padrão deve ser usada e quando deve ser usada uma classe abstrata (com método (s) abstrato)? As classes abstratas ainda são úteis nesse cenário?
java
interface
java-8
abstract-class
default-method
Narendra Pathai
fonte
fonte
Respostas:
Há muito mais nas classes abstratas do que implementações de métodos padrão (como estado privado), mas a partir do Java 8, sempre que você tiver a opção de escolher, você deve usar o
default
método defender (aka. ) Na interface.A restrição no método padrão é que ele pode ser implementado apenas nos termos de chamadas para outros métodos de interface, sem referência ao estado de uma implementação específica. Portanto, o principal caso de uso são os métodos de nível superior e de conveniência.
O bom desse novo recurso é que, onde antes você era forçado a usar uma classe abstrata para os métodos de conveniência, restringindo o implementador a uma herança única, agora você pode ter um design realmente limpo, com apenas a interface e um mínimo de implementação esforço forçado ao programador.
A motivação original para introduzir
default
métodos no Java 8 era o desejo de estender as interfaces do Collections Framework com métodos orientados a lambda sem interromper nenhuma implementação existente. Embora isso seja mais relevante para os autores das bibliotecas públicas, você também pode encontrar o mesmo recurso útil no seu projeto. Você tem um local centralizado para adicionar nova comodidade e não precisa confiar na aparência do restante da hierarquia de tipos.fonte
Existem algumas diferenças técnicas. As classes abstratas ainda podem fazer mais em comparação com as interfaces Java 8:
Conceitualmente, o principal objetivo dos métodos de defesa é uma compatibilidade com versões anteriores após a introdução de novos recursos (como funções lambda) no Java 8.
fonte
public static final
campos de uma interface como "estado". Astatic
parte significa que eles não estão relacionados a uma instância específica. Eles são atribuídos na instanciação de classe , que não é a mesma que após a criação da instância .Isso está sendo descrito neste artigo . Pense em
forEach
coleções.fonte
AbstractList::forEach
umUnsupportedOperationException
.Estes dois são bem diferentes:
Os métodos padrão são adicionar funcionalidade externa às classes existentes sem alterar seu estado.
E classes abstratas são um tipo normal de herança, são classes normais que devem ser estendidas.
fonte
Conforme descrito neste artigo,
Classes abstratas versus interfaces em Java 8
fonte
Em relação à sua consulta de
documentação java fornece resposta perfeita.
Classes abstratas comparadas às interfaces:
Os casos de uso de cada um deles foram explicados abaixo na postagem do SE:
Qual é a diferença entre uma interface e uma classe abstrata?
Sim. Eles ainda são úteis. Eles podem conter métodos e atributos não estáticos e não finais ( protegidos, privados e públicos ), o que não é possível mesmo nas interfaces Java-8.
fonte
Sempre que temos uma escolha entre classe abstrata e interface, devemos sempre (quase) preferir métodos padrão (também conhecidos como defensor ou extensões virtuais).
Collection and AbstractCollection
. Agora devemos implementar os métodos na própria interface para fornecer a funcionalidade padrão. As classes que implementam a interface têm a opção de substituir os métodos ou herdar a implementação padrão.Outro uso importante dos métodos padrão é
interface evolution
. Suponha que eu tenha uma classe Ball como:public class Ball implements Collection { ... }
Agora, no Java 8, um novo recurso é introduzido. Podemos obter um fluxo usando o
stream
método adicionado à interface. Sestream
não fosse um método padrão, todas as implementações daCollection
interface teriam sido interrompidas, pois não estariam implementando esse novo método. Adicionar um método não padrão a uma interface não ésource-compatible
.Mas suponha que não recompilemos a classe e utilizemos um arquivo jar antigo que contenha essa classe
Ball
. A classe carregará bem sem esse método ausente, instâncias podem ser criadas e parece que tudo está funcionando bem. MAS se o programa invocar ostream
método, por exemploBall
, obteremosAbstractMethodError
. Então, tornar o método padrão resolveu os dois problemas.fonte
Os métodos padrão na interface Java permitem a evolução da interface .
Dada uma interface existente, se você deseja adicionar um método sem interromper a compatibilidade binária com versões mais antigas da interface, você tem duas opções disponíveis: adicionar um método padrão ou estático. De fato, qualquer método abstrato adicionado à interface teria que ser implementado pelas classes ou interfaces que implementam essa interface.
Um método estático é exclusivo para uma classe. Um método padrão é exclusivo para uma instância da classe.
Se você adicionar um método padrão a uma interface existente, as classes e interfaces que implementam essa interface não precisam implementá-lo. Eles podem
Mais sobre o tópico aqui .
fonte
Embora seja uma pergunta antiga, deixe-me dar minha opinião sobre isso também.
classe abstrata: dentro da classe abstrata, podemos declarar variáveis de instância, que são necessárias para a classe filho
Interface: Dentro da interface, todas as variáveis são sempre estáticas e finais públicas, não podemos declarar variáveis de instância
classe abstrata: a classe abstrata pode falar sobre o estado do objeto
Interface: a interface nunca pode falar sobre o estado do objeto
classe abstrata: Dentro da classe abstrata podemos declarar construtores
Interface: Na interface interna, não podemos declarar construtores, pois o objetivo dos
construtores é inicializar variáveis de instância. Então, qual é a necessidade do construtor se não pudermos ter variáveis de instância nas interfaces .
classe abstrata: dentro da classe abstrata podemos declarar blocos estáticos e de instância
Interface: As interfaces não podem ter blocos estáticos e de instância.
classe abstrata: classe abstrata não pode se referir à expressão lambda
Interfaces: interfaces com método abstrato único podem se referir à expressão lambda
classe abstrata : dentro da classe abstrata, podemos substituir os métodos OBJECT CLASS
Interfaces: Não podemos substituir os métodos OBJECT CLASS dentro de interfaces.
Terminarei com a observação de que:
Os conceitos de método padrão / conceitos de método estático na interface vieram apenas para salvar as classes de implementação, mas não para fornecer uma implementação útil significativa. Métodos padrão / métodos estáticos são um tipo de implementação fictícia ", se você quiser, pode substituí-los ou substituí-los (no caso de métodos padrão) na classe de implementação", evitando assim a implementação de novos métodos nas classes de implementação sempre que novos métodos nas interfaces são adicionados. Portanto, as interfaces nunca podem ser iguais às classes abstratas.
fonte
A regra Remi Forax é Você não cria com as classes Abstratas. Você cria seu aplicativo com interfaces . Watever é a versão do Java, qualquer que seja a linguagem. É apoiada pela eu princípio segregação nterface em SOL I D princípios.
Posteriormente, você pode usar classes Abstratas para fatorar o código. Agora, com o Java 8, você pode fazer isso diretamente na interface. Esta é uma instalação, não mais.
fonte
Compatibilidade com versões anteriores: imagine que sua interface seja implementada por centenas de classes, modificando essa interface forçará todos os usuários a implementar o método recém-adicionado, mesmo que não seja essencial para muitas outras classes que implementam sua interface. Além disso, permite que sua interface ser uma interface funcional
Fatos e Restrições:
1-Só pode ser declarado dentro de uma interface e não dentro de uma classe ou classe abstrata.
2-Deve fornecer um corpo
3-Não é assumido que seja abstrato como outros métodos normais usados em uma interface.
fonte
No Java 8, uma interface se parece com uma classe abstrata, embora possam haver algumas diferenças, como:
1) Classes abstratas são classes, portanto, não estão restritas a outras restrições da interface em Java, por exemplo, a classe abstrata pode ter o estado , mas você não pode ter o estado na interface em Java.
2) Outra diferença semântica entre a interface com métodos padrão e a classe abstrata é que você pode definir construtores dentro de uma classe abstrata , mas não pode definir construtor dentro da interface em Java
fonte
Os métodos padrão na Interface Java devem ser usados mais para fornecer implementação fictícia de uma função, poupando assim qualquer classe de implementação dessa interface do trabalho de declarar todos os métodos abstratos, mesmo que eles desejem lidar com apenas um. Os métodos padrão na interface são, de certa forma, mais um substituto para o conceito de classes de adaptadores.
Os métodos na classe abstrata devem, no entanto, fornecer uma implementação significativa que qualquer classe filho deve substituir somente se necessário para substituir uma funcionalidade comum.
fonte
Como mencionado em outras respostas, a capacidade de adicionar implementação a uma interface foi adicionada para fornecer compatibilidade com versões anteriores na estrutura Coleções. Eu argumentaria que fornecer compatibilidade com versões anteriores é potencialmente a única boa razão para adicionar implementação a uma interface.
Caso contrário, se você adicionar implementação a uma interface, estará violando a lei fundamental do motivo pelo qual as interfaces foram adicionadas em primeiro lugar. Java é uma linguagem de herança única, diferentemente do C ++, que permite herança múltipla. As interfaces fornecem os benefícios de digitação que vêm com um idioma que suporta herança múltipla sem introduzir os problemas que acompanham a herança múltipla.
Mais especificamente, o Java permite apenas herança única de uma implementação, mas permite herança múltipla de interfaces. Por exemplo, o seguinte é um código Java válido:
MyObject
herda apenas uma implementação, mas herda três contratos.Java transmitiu herança múltipla de implementação porque a herança múltipla de implementação vem com uma série de problemas espinhosos, que estão fora do escopo desta resposta. As interfaces foram adicionadas para permitir a herança múltipla de contratos (aka interfaces) sem os problemas de herança múltipla da implementação.
Para apoiar meu argumento, aqui está uma citação de Ken Arnold e James Gosling do livro The Java Programming Language, 4th edition :
fonte
Por favor, pense primeiro no princípio aberto / fechado. Os métodos padrão nas interfaces O VIOLAM. Este é um recurso ruim em Java. Ele incentiva o design ruim, a arquitetura ruim e a baixa qualidade do software. Eu sugeriria evitar o uso completo de métodos padrão.
Faça a si mesmo algumas perguntas: Por que você não pode colocar seus métodos na classe abstrata? Você precisaria então de mais de uma classe abstrata? Em seguida, pense sobre o que é sua classe responsável. Você tem certeza de que todos os métodos que você vai colocar na classe realmente cumprem o mesmo propósito? Pode ser que você distinga vários propósitos e depois divida sua classe em várias classes, para cada finalidade sua própria classe.
fonte