[picture]

Interfaces

Programação 3: Orientação a Objetos e Java


Como vimos anteriormente, classes são agrupamentos de objetos que têm atributos em comum e podem realizar as mesmas operações. Em Java, a definição de classes é o mecanismo básico para definição de tipos de objetos.

No entanto, às vezes pode ser necessário agrupar objetos de classes diferentes visando explorar os aspectos comuns aos mesmos. De fato, objetos podem ter a capacidade de realizar o mesmo tipo de operação, apesar de não serem da mesma classe, não terem atributos em comum e não realizarem exatamente as mesmas operações. Por exemplo, considere os objetos das classes Banco e BancoAr, os quais podem realizar operações do tipo

  public void cadastro(Conta c)
mas que não são exatamente a mesma operação: qualquer conta pode ser cadastrada em um objeto (banco) de Banco, enquanto só contas com saldo maior que 100 podem ser cadastradas em objetos de BancoAr.

Através da definição de interfaces pode-se representar em Java agrupamentos de objetos que apenas oferecem os mesmos tipos de serviços (tipos de operações), não sendo necessariamente da mesma classe. Desta forma, interfaces definem tipos de objetos similarmente a classes, só que de uma maneira bem mais flexível, permitindo inclusive agrupar objetos com implementações e comportamentos totalmente diferentes.

Para definir uma interface basta então apresentar os tipos de operações que podem ser realizadas pelos objetos do agrupamento associado a interface. Por exemplo, a seguir definimos uma interface correspondendo ao agrupamento de quaisquer bancos ( não importando como o banco é implementado) que tenham operações para cadastrar contas, além de verificar o saldo total e o número de clientes (contas) do banco:

  interface QQBanco {
    void cadastro(Conta c);
    double saldo_total();
    int num_clientes();
  }
Note que como na definição de interfaces pode-se especificar apenas o tipo dos serviços oferecidos, não como eles são implementados, coloca-se ";" ao invés do corpo dos métodos.

Outra particularidade de interfaces é que os métodos introduzidos são implicitamente qualificados como public. Além de métodos, interfaces podem também introduzir constantes, que em Java são declaradas como variáveis finais, isto é, que não podem ser modificadas. Por exemplo, uma constante n de tipo inteiro é declarada da seguinte maneira:

  final int	n = 27;
onde final é um qualificador especial que indica que a variável é final.

Similarmente a classes, interfaces são usadas como tipos de objetos. Por exemplo, uma classe de auditores que podem investigar qualquer banco oferecendo os serviços especificados por QQBanco é definida da seguinte maneira:

  public class NAuditor {
    private String	nome;

    public void investiga_banco(QQBanco b) {
      if ((b.saldo_total() / b.num_clientes()) > 500.55)
         System.out.println("Banco aprovado!");
      else System.out.println("Banco não aprovado!");
    }
  }
Assim os auditores desta classe podem avaliar bancos implementados de maneiras diferentes e oferecendo serviços diferentes, como no caso de Banco e BancoAr. Note que sem interfaces, teríamos que duplicar código, tendo uma classe Auditor que investiga bancos de tipo Banco, e uma classe AuditorAr que investiga bancos de tipo BancoAr.

Mas uma vez definida uma interface, temos que indicar explicitamente as classes que implementam a interface; isto é, temos que dizer que classes são formadas por objetos que oferecem os serviços especificados pela interface. Só assim estaremos garantindo que os objetos destas classes são parte do agrupamento associado à interface; isto não é deduzido automaticamente a partir da definição das classes e da interface.

Note que assim estaremos especificando que os tipos definidos por estas classes são, de fato, subtipos do tipo definido pela interface. Naturalmente, isto implica que qualquer objeto das classes pode ser usado quando se espera um objeto da interface.

Por exemplo, para indicar que as classes Banco e BancoAr implementam a interface QQBanco temos que definir as classes da seguinte maneira:

class Banco implements QQBanco {...}

class BancoAr implements QQBanco {...}
onde implements é seguido de uma lista de nomes de interfaces separados por vírgulas, indicando as interfaces que são implementadas pela classe. Só com estas novas definições das classes é que objetos de NAuditor podem investigar bancos de Banco e BancoAr.


Paulo Borba (phmb@di.ufpe.br)