Lembro ter lido no livro de certificação da Kathy Sierra que em uma interface só posso criar constantes.
Isso é verdade? Pergunto porque estou conseguindo adicionar uma lista dentro de uma interface e usá-la. Seguem os códigos:
import java.util.ArrayList;
import java.util.List;
public interface ContatoDAO {
List<String> contatos = new ArrayList<String>();
public void inserir(String nome);
}
public class ContatoDAOImpl implements ContatoDAO {
@Override
public void inserir(String nome) {
contatos.add(nome);
}
}
public class TesteDao {
public static void main(String[] args) {
ContatoDAO c = new ContatoDAOImpl();
c.inserir("Ana");
c.inserir("Maria");
for (String nome : ContatoDAO.contatos) {
System.out.println(nome);
}
}
}
Veja bem, constante é uma coisa, objeto imutável é completamente diferente. Em uma interface você pode perfeitamente criar uma constante que aponte para um objeto mutável. No seu caso, você pode manipular a lista contatos normalmente, porém, uma vez que essa variável foi inicializada, você não consegue atribuir uma nova lista para ela. Por exemplo, o código:
public class ContatoDAOImpl implements ContatoDAO {
@Override
public void inserir(String nome) {
contatos.add(nome);
}
public void resetContatos(){
contatos = new ArrayList<>();
}
}
não compila.
De qualquer maneira, as variáveis que podem ser declaradas em interfaces, além de final são estáticas e públicas. Ou seja, se você tiver 4 objetos que implementam a interface ContatoDAO, as 4 instâncias apontarão para a mesma lista.
Se você precisa definir uma variável em um supertipo, isso é um detalhe de implementação. Portanto, a ferramenta que deve ser usada deve ser uma classe ou classe abstrata.
Embora você possa fazer algumas coisas, você não deve fazer tais coisas. Em interfaces, limite-se a declarar métodos.
A declaração de constantes (tecnicamente: membros públicos, estáticos e finais) é algo que não é recomendável em interfaces. (Só existe por ser um efeito colateral de não ter havido tempo de definir a palavra-chave “enum” quando o Java 1.0 foi lançado )
Quando você escreve
List<String> contatos = new ArrayList<String>()
em uma interface, na verdade está escrevendo:
public static final List<String> contatos = new ArrayList<String>();