Interfaces

Computação II - Ciência da Computação


Prof.: Danilo S. Carvalho

Nessa aula, falaremos do recurso que nos permite categorizar nossos objetos de acordo apenas com o comportamento ou capacidade deles, em vez de suas características.


Ao final da aula, entenderemos a ideia de um contrato de interface, e como aplicar no Java.

A herança nos permite organizar os nossos conceitos hierarquicamente, reusando as características e comportamento de nossas classes.


Entretanto, possui duas limitações importantes:

  1. Não é possível herdar de múltiplas classes em Java, pois a linguagem não fornece um meio de resolver conflitos entre atributos de classes distintas.
  2. Não há uma forma de especificar comportamento ou capacidade desejado de uma classe, independente da implementação.

Um exemplo desse problema é quando queremos atribuir capacidades comum à hierarquias de classes distintas.


Árvores e casas são imóveis, assim como pessoas e carros são móveis. Podemos querer atribuir a mobilidade como um comportamento comum entre objetos e esperar certas capacidades deles.


Mas faria sentido pessoas e carros serem derivados da mesma superclasse?

Para resolver ambos esses problemas, a linguagem Java oferece o recurso das interfaces.

Uma interface é similar a uma classe, mas descreve apenas comportamento ou capacidade esperados.

É declarada com a palavra chave interface, em vez de class.

Como só descreve comportamento/capacidade, uma interface não possui atributos de instância, mas pode possuir constantes static.

Essas constantes devem ser marcadas com a palavra chave final (aprenderemos sobre final mais adiante).

Os métodos da interface não possuem implementação. São portanto chamados de métodos abstratos.

                        
                            public interface Movel {
                                
                            }
                        
                    
                        
                            public interface Movel {
                                public static final CONST_MOVIMENTO = 0.5;
                            }
                        
                    
                        
                            public interface Movel {
                                public static final CONST_MOVIMENTO = 0.5;

                                public void mover();
                            }
                        
                    

Podemos atribuir o comportamento descrito por uma interface a uma classe fazendo a classe implementar a interface.

Isso é feito no Java através da palavra chave implements:

Uma vez que a classe implemente uma interface, ela deve implementar o corpo de cada um dos métodos definidos na interface, do contrário o programa não compila.

Uma classe pode implementar mais de uma interface, representando suas múltiplas capacidades.

                        
                            public class Pessoa implements Movel {
                                ...
                            }
                        
                    
                        
                            public class Pessoa implements Movel {
                                ...

                                public void mover() {
                                    ...  // Implementação do método da interface.
                                }
                            }
                        
                    
                        
                            public class Pessoa implements Movel, Autenticavel {
                                ...

                                public void mover() {
                                    ...  // Implementação do método da interface.
                                }
                            }
                        
                    

Uma interface é também um tipo, representando todos os que compartilham aquele comportamento ou capacidade.

Dessa forma, podemos atribuir a referência de um objeto que implemente a interface a uma váriavel do tipo da interface.

Entretanto, uma interface não pode ser instanciada.

Essa noção de que podemos passar uma referência de um objeto contando que ele possui certas capacidades garantida pela interface é chamada de contrato de interface.

O contrato garante que um objeto vai poder chamar certos métodos, independente do que esteja representando.

Além disso, uma interface pode herdar de uma ou mais interfaces usando o extends.

                        
                            Movel coisaMovel = new Pessoa();
                        
                    
                        
                            Movel coisaMovel = new Movel();  // Erro de compilação.
                        
                    
                        
                            public static void moverObjeto(Movel objetoMovel) {
                                ...  // Esse método pode mover o argumento, garantido pelo contrato de interface.
                            }
                        
                    
                        
                            public interface Flexivel extends Maleavel, Ductil {
                                ...  
                            }
                        
                    

Agora já é possível definir as características e capacidades dos objetos de forma independente.


Com as interfaces podemos definir tipos que determinam apenas aquilo que queremos que um objeto seja capaz de fazer, sem precisar definir o como.


O contrato de interface garante o que um objeto pode fazer, independente de sua classe.

Perguntas:

  1. Como o uso de métodos de interface se assemelha aos métodos virtuais e como são diferentes?
  2. Encontre 4 exemplos de interfaces na JDK e explique as capacidades descritas por elas. Qual é o motivo delas existirem?

Exercício:

  1. Considerando as alterações feitas no sistema da biblioteca para o exercício da aula sobre herança, simplifique a tipagem futura através do uso de interfaces.

Até a próxima aula!