Uma interface em Java é semelhante a uma classe, mas o corpo de uma interface pode incluir apenas métodos abstratos e
final
campos (constantes).
Recentemente, vi uma pergunta parecida com esta
interface AnInterface {
public default void myMethod() {
System.out.println("D");
}
}
De acordo com a definição da interface, apenas métodos abstratos são permitidos. Por que me permite compilar o código acima? Qual é a default
palavra - chave?
Por outro lado, quando eu estava tentando escrever o código abaixo, ele dizia modifier default not allowed here
default class MyClass{
}
ao invés de
class MyClass {
}
Alguém pode me dizer o propósito da default
palavra - chave? É permitido apenas dentro de uma interface? Como ele difere de default
(sem modificador de acesso)?
Respostas:
É um novo recurso do Java 8 que permite
interface
fornecer uma implementação. Descrito em Java 8 JLS-13.5.6. Declarações de método de interface que lê (em parte)O que há de novo no JDK 8 diz (em parte)
fonte
private
métodos.private
métodos não fazem realmente parte da interface, mas podem servir como métodos auxiliares para asdefault
implementações ou em inicializadores constantes. Observe que eles já existem no Java 8, pois, quando você usa expressões lambda em interfaces,private
métodos sintéticos são gerados. Portanto, o Java 9 permite que você use esse recurso para usos não sintéticos, não lambda também ...Métodos padrão foram adicionados ao Java 8 principalmente para oferecer suporte a expressões lambda. Os designers (habilmente, na minha opinião) decidiram fazer a sintaxe lambdas para criar implementações anônimas de uma interface. Mas dados lambdas só podem implementar um único método, eles seriam limitados a interfaces com um único método, o que seria uma restrição bastante severa. Em vez disso, os métodos padrão foram adicionados para permitir o uso de interfaces mais complexas.
Se você precisar de algum convencimento da afirmação que
default
foi introduzida devido aos lambdas, observe que a proposta do espantalho do Projeto Lambda, de Mark Reinhold, em 2009, menciona 'Métodos de extensão' como um recurso obrigatório a ser adicionado para suportar lambdas.Aqui está um exemplo que demonstra o conceito:
interface Operator { int operate(int n); default int inverse(int n) { return -operate(n); } } public int applyInverse(int n, Operator operator) { return operator.inverse(n); } applyInverse(3, n -> n * n + 7);
Muito artificial eu percebo, mas devo ilustrar como
default
suporta lambdas. Porinverse
ser um padrão, ele pode ser facilmente substituído por uma classe de implementação, se necessário.fonte
Algo que foi esquecido nas outras respostas foi seu papel nas anotações. Já em Java 1.5, a
default
palavra - chave surgiu como um meio de fornecer um valor padrão para um campo de anotação.@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface Processor { String value() default "AMD"; }
Seu uso foi sobrecarregado com a introdução do Java 8 para permitir a definição de um método padrão nas interfaces.
Outra coisa que foi esquecida: a razão pela qual a declaração
default class MyClass {}
é inválida é devido à forma como as classes são declaradas . Não há nenhuma disposição no idioma que permite que essa palavra-chave apareça lá. Ele não aparecer para declarações de métodos de interface , no entanto.fonte
Um novo conceito é introduzido no Java 8, chamado de métodos padrão. Os métodos padrão são aqueles métodos que têm alguma implementação padrão e ajudam na evolução das interfaces sem quebrar o código existente. Vejamos um exemplo:
public interface SimpleInterface { public void doSomeWork(); //A default method in the interface created using "default" keyword default public void doSomeOtherWork(){ System.out.println("DoSomeOtherWork implementation in the interface"); } } class SimpleInterfaceImpl implements SimpleInterface{ @Override public void doSomeWork() { System.out.println("Do Some Work implementation in the class"); } /* * Not required to override to provide an implementation * for doSomeOtherWork. */ public static void main(String[] args) { SimpleInterfaceImpl simpObj = new SimpleInterfaceImpl(); simpObj.doSomeWork(); simpObj.doSomeOtherWork(); } }
e a saída é:
Implementação Do Some Work na classe
Implementação DoSomeOtherWork na interface
fonte
O novo recurso Java 8 ( métodos padrão ) permite que uma interface forneça uma implementação quando é rotulada com a
default
palavra - chave.Por exemplo:
interface Test { default double getAvg(int avg) { return avg; } } class Tester implements Test{ //compiles just fine }
Teste de interface usa a palavra-chave padrão que permite à interface fornecer uma implementação padrão do método sem a necessidade de implementar esses métodos nas classes que usam a interface.
Compatibilidade com versões anteriores: imagine que sua interface é implementada por centenas de classes, modificar essa interface forçará todos os usuários a implementar o método recém-adicionado, embora não seja essencial para muitas outras classes que implementam sua interface.
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 se presume ser público ou abstrato como outros métodos normais usados em uma interface.
fonte
Os métodos padrão em uma interface nos permitem adicionar novas funcionalidades sem quebrar o código antigo.
Antes do Java 8, se um novo método fosse adicionado a uma interface, todas as classes de implementação dessa interface eram obrigadas a substituir esse novo método, mesmo que não usassem a nova funcionalidade.
Com o Java 8, podemos adicionar a implementação padrão para o novo método usando a
default
palavra - chave antes da implementação do método.Mesmo com classes anônimas ou interfaces funcionais, se virmos que algum código é reutilizável e não quisermos definir a mesma lógica em todo o código, podemos escrever implementações padrão dessas e reutilizá-las.
Exemplo
public interface YourInterface { public void doSomeWork(); //A default method in the interface created using "default" keyword default public void doSomeOtherWork(){ System.out.println("DoSomeOtherWork implementation in the interface"); } } class SimpleInterfaceImpl implements YourInterface{ /* * Not required to override to provide an implementation * for doSomeOtherWork. */ @Override public void doSomeWork() { System.out.println("Do Some Work implementation in the class"); } /* * Main method */ public static void main(String[] args) { SimpleInterfaceImpl simpObj = new SimpleInterfaceImpl(); simpObj.doSomeWork(); simpObj.doSomeOtherWork(); } }
fonte
Uma explicação muito boa é encontrada nos Tutoriais Java ™ , parte da explicação é a seguinte:
Considere um exemplo que envolve fabricantes de carros controlados por computador que publicam interfaces padrão da indústria que descrevem quais métodos podem ser invocados para operar seus carros. E se esses fabricantes de carros controlados por computador adicionassem novas funcionalidades, como vôo, a seus carros? Esses fabricantes precisariam especificar novos métodos para permitir que outras empresas (como fabricantes de instrumentos eletrônicos de orientação) adaptassem seu software a carros voadores. Onde esses fabricantes de automóveis declarariam esses novos métodos de voo? Se eles os adicionarem às suas interfaces originais, os programadores que implementaram essas interfaces teriam que reescrever suas implementações. Se eles os adicionarem como métodos estáticos, os programadores os considerarão como métodos utilitários, não como métodos essenciais essenciais.
Os métodos padrão permitem adicionar nova funcionalidade às interfaces de suas bibliotecas e garantir compatibilidade binária com código escrito para versões anteriores dessas interfaces.
fonte
Os métodos padrão permitem que você adicione novas funcionalidades às interfaces de seus aplicativos. Também pode ser usado para ter uma herança múltipla . Além dos métodos padrão, você pode definir métodos estáticos nas interfaces. Isso torna mais fácil para você organizar métodos auxiliares
fonte