Interface e Polimorfismo na Prática

Aula de Laboratório

Objetivos:

Criar e utilizar interfaces

Trabalhar com polimorfismo.

 

Abra o ambiente de sua preferência e crie um novo projeto para esta aula (não esqueça de salvá-lo no drive h).

Já vimos que uma interface é, essencialmente, uma coleção de constantes e métodos abstratos, que pode ter a implementação de métodos default e abstract a partir da versão 8 do Java. Uma classe pode implementar uma ou mais interfaces, o que significa que ela deverá implementar, além dos seus próprios métodos, todos os outros métodos definidos na interface. Uma interface não pode ser instanciada, mas é possível criar referências do tipo interface para armazenar objetos das classes que a implementam.

Para testar a utilização de interfaces, vamos considerar que será implementado um editor gráfico no qual o usuário pode criar instâncias de pontos, retângulos e círculos. Portanto, será necessário criar um conjunto de classes para representar as primitivas gráficas. Para facilitar a programação através da padronização, estas classes deverão implementar a interface apresentada abaixo. A implementação da classe Ponto também está apresentada a seguir para exemplificar a implementação de interface.

public interface PrimitivaGrafica

{

     public final static double PI = 3.1416;

     public abstract double area();

     public abstract void setEspessura(int e);

     public abstract String getNome();

}

public class Ponto implements PrimitivaGrafica

{

    private double x;

    private double y;

    private int espessura;

 

    public Ponto(double x, double y, int e) {

        this.x = x;

        this.y = y;

        setEspessura(e);

    }

   

    public void setX (double xVal) {

        x = xVal;

    }

 

    public void setY (double yVal) {

        y = yVal;

    }

 

    public double getX() {

        return(x);

    }

 

    public double getY() {

        return(y);

    }

 

    public String toString() {

         String str = "Ponto (" + x + "," + y + ") com tamanho " + espessura;

         return str;

    }

   

     public double area() {

         return 0;

     }

    

     public void setEspessura(int e) {

         // Nesta classe, espessura indica o tamanho do ponto

         if (e>0)

            espessura = e;

     }

       

     public String getNome(){

         return ("Ponto");

     }

}

 

Exercício:

  • Inclua a interface e a classe apresentada acima no projeto criado (coloque a interface em um arquivo e a classe em outro).

·         Implemente uma classe Retângulo que implementa a interface PrimitivaGrafica e possui como atributos dois objetos do tipo Ponto e uma espessura (especifica o número de pixels da linha usada para desenhar o retângulo). Esta classe deverá ter um construtor e implementar o método toString().

·         Implemente uma classe Circulo que implementa a interface PrimitivaGrafica e possui como atributos uma referência para Ponto, um raio e uma espessura. Esta classe deverá ter um construtor e implementar o método toString().

·         Implemente uma classe CadastroDePrimitivas que tenha como atributo um ArrayList para armazenar objetos Ponto, Retangulo e Circulo. Inclua um método para incluir uma primitiva gráfica, que pode ser Ponto, Retangulo ou Circulo. Inclua também um método para percorrer o ArrayList e imprimir todos os dados de todos os objetos armazenados. Por exemplo:
Circulo com centro em (2,2) e raio 1, cuja espessura da linha é 2.
Retângulo que vai de (1,1) a (3,3) com espessura de linha 1.
Ponto que está na coordenadas (1,5) com tamanho 3.
Circulo com centro em (3,4) e raio 3, cuja espessura da linha é 1.
Circulo com centro em (0,0) e raio 2, cuja espessura da linha é 3.
Retângulo que vai de (0,0) a (-2,-2) com espessura de linha 3.
Ponto que está na coordenadas (2,2) com tamanho 1.

·         Inclua um método na classe CadastroDePrimitivas para retornar o total de pontos existentes no cadastro (public int getTotalPontos()) e um método para retornar o ponto com menor valor para a coordenada x (public Ponto getPontoComMenorX ()).

·         Crie uma classe App que tenha o método main e instancia o cadastro, inclui vários objetos dentro dele e chama todos os métodos implementados.


Nós estudamos que para usar o método de classe sort da classe Collections, que permite ordenar uma coleção, é necessário armazenar dentro da coleção (por exemplo, do ArrayList) um objeto que implementa a interface Comparable. Ao implementar esta interface, é obrigatório que o método compareTo seja implementado. Este método é chamado dentro de sort para fazer a ordenação.

A classe String implementa esta interface. Portanto, para ver o seu funcionamento, acrescente na classe teste os comandos listados a seguir:

        List<String> nomes = new ArrayList<String>();

        nomes.add("Julio Machado");

        nomes.add("Isabel Manssour");

        nomes.add("Bernardo Copstein");

        Collections.sort(nomes);

        System.out.println(nomes);

Considere agora a classe País apresentada abaixo:

public class Pais implements Comparable<Pais>

{

     private String nome;

     private float area;

    

     public Pais(String n, float a)   {

         nome = n;

         area = a;

     }

    

     public float getArea() {

         return area;

     }

    

     public String getNome() {

         return nome;

     }

    

    public int compareTo(Pais p) {

    if (this.area < p.area) return -1;

    if (this.area > p.area) return 1;

    return 0;

    }

   

    public String toString() {

    return nome + " tem área de " + area + " km2";

    }

}

 

Exercício:

  • Crie na classe Teste um ArrayList de países. Inclua 4 países com diferentes nomes e áreas. Depois ordene o ArrayList e mande imprimir os dados de cada país usando um foreach para percorrer o ArrayList.

 

Suponha que agora seja necessário ordenar uma lista de países pelo nome do país ao invés de sua área. Não é prático redefinir o método compareTo() toda vez que alterarmos a condição de ordenação, certo?

Portanto, existe um segundo método de ordenação chamado sort(List, Comparator). Este método ordena uma lista de acordo com os critérios de ordenação fornecidos pelo objeto que implementa a interface Comparator.

A interface Comparator requer o seguinte método: int compare(Object a, Object b)

Agora, a coleção de objetos pode conter qualquer objeto, sem a necessidade que eles implementem a interface Comparable.

Copie para o seu projeto e execute o exemplo a seguir:

 

import java.util.*;

public class PaisComparadorNome implements Comparator<Pais>

{

    public int compare(Pais p1, Pais p2)

    {

        return p1.getNome().compareTo(p2.getNome());

    }

}

 

...

     public static void main(String args[])

     {

         ArrayList<Pais> paises = new ArrayList<Pais>();

         paises.add(new Pais("Uruguai", 176220));

         paises.add(new Pais("Tailandia", 514000));

         paises.add(new Pais("Belgica", 30510));

         Collections.sort(paises, new PaisComparadorNome());

         for (Pais p : paises)

         {

             System.out.println(p.getNome() + " " + p.getArea());

         }
        ...
 


 

Exercício:

  • Crie uma classe PaisComparadorArea para fazer a comparação dos países pela área, e não pelo nome.

·         Acrescente no método main uma chamada para o método sort de maneira que o ArrayList de países seja ordenado pela área. Depois mande imprimir os dados de cada país usando um foreach para percorrer o ArrayList.

·         Experimente fazer a ordenação pelo processo simplificado do Java 8. Veja o exemplo abaixo e altere para que a ordenação seja feita por área.

List<Pais> a= new ArrayList<Pais>();
a.sort(  (Pais l1, Pais l2) -> l1.getNome().compareTo(l2.getNome()) );

·         Dada a classe Professor apresentada abaixo, faça alterações para que seja possível ordenar coleções de professores por nome (ascendente e descendente), por matrícula e por carga horária.

public class Professor {
    private String nome;
    private int matricula;
    private int cargaHoraria;
    public Professor(String n, int m, int c){
        nome = n; matricula = m; cargaHoraria = c;
    }   
    public void setMatricula(int m){ matricula = m; }
    public void setCargaHoraria(int c){ cargaHoraria = c; }
    public String getNome(){ return nome; }
    public int getMatricula(){ return matricula; }
    public int getCargaHoraria(){ return cargaHoraria; }
    public String toString(){
        return ("Nome: "+nome+"\nMatrícula: "+matricula
                       +"\nCarga horária: "+cargaHoraria);
    }
}

 

 

Não deixe o laboratório se houver alguma dúvida com relação a:

  • criação e utilização de interfaces !!  

 

PS: exercícios adaptados da aula do prof. Julio Machado.