Preferência por interfaces como tipos de referência:
Se uma interface adequada existir, você deve referenciar objetos por meio dela em vez da classe concreta.
Isso se aplica a parâmetros, valores de retorno, variáveis e campos.
Flexibilidade ao usar interfaces:
Usar interfaces permite trocar a implementação sem afetar o código.
Exemplo: trocando de LinkedHashSet para HashSet ou TreeSet, basta alterar o construtor.
Quando NÃO usar interfaces:
Funcionalidade específica da implementação:
Se uma implementação oferece algo não exigido pela interface (ex.: LinkedHashSet garante ordem de iteração, mas HashSet não).
Sem uma interface apropriada:
Algumas classes como String ou BigInteger não têm interfaces equivalentes e devem ser usadas diretamente.
Frameworks baseados em classes:
Exemplo: OutputStream no pacote java.io é referenciado por meio de uma classe abstrata, não uma interface.
Métodos específicos da implementação:
Exemplo: PriorityQueue implementa Queue, mas tem um método comparator() não presente em Queue. Só use a classe se precisar desse método extra.
Benefício:
Usar interfaces torna o programa mais flexível e modular, permitindo alterar implementações facilmente sem quebrar o código existente.
Exemplos de Código
Bom exemplo: Usar interface como tipo
Set<String> s = new LinkedHashSet<>();
Mau exemplo: Usar a classe concreta como tipo
LinkedHashSet<String> s = new LinkedHashSet<>();
Flexibilidade: Alterando a implementação sem afetar o código
Set<String> s = new TreeSet<>();
Exemplo de uso de uma classe final como String
String str = "Hello";
Exemplo de uso de classe base de um framework
OutputStream output = new FileOutputStream("file.txt");
Top comments (0)