O que pode ser declarado em uma interface?

Prezados,

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.

No meu ponto de vista, se você está criando variáveis dentro da interface é uma má prática… POR QUÊ???

A interface é um conceito para se utilizar… mais ou menos um contrato.

Acredito que para manipulação é melhor trabalhar em suas classes.

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 :frowning: )

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>();