Caminho de Navegação Java / Artigos / 10º aula de java

Java

 

Nenhuma avalição
Indique ao Ueba Indique ao BlogBlogs Indique ao Delicious Indique ao Technorati Indique ao Google Bookmarks Indique ao Newsgator
TAGS

Nenhuma tag foi definida ainda!

Defina as tags para esta página preenchendo o campo abaixo.

  • Máximo de 100 tags
  • Cada tag deve ter até 20 caracteres.
  • Separar as tags com virgula. Ex.: php, sql, html, xml, fireworks
COMENTAR

INDICAR
Nome do amigo: E-mail do amigo: Comentário:
REPORTAR ERRO Descreva o erro:

10º aula de javaPostada em: 19/05/2005

David Ramires
Por: David Ramires Nº de Visualizações: 1568.



Interfaces e polimorfismo.

Vamos considerar um exemplo de uma classe chamada ConjuntoNumerico que possa receber números e nos retornar a média dos valores recebidos e o maior (máximo) valor recebido. O código de tal classe poderia ser o seguinte:

class ConjuntoNumerico
{
private int num;
private double soma;
private double maximo;

public ConjuntoNumerico() {
num = 0;
soma = 0;
maximo = 0;
}
public void add(double x) {
soma += x();
if (num==0 || maximo < x)
{
maximo = x;
}
num++;
}
public double media() {
return (num>0?soma/num:0);
}
public double getMaximo() {
return maximo;
}
}

E um programa para testá-la seria:

class TesteConjunto
{
public static void main(String[] args)
{
ConjuntoNumerico c = new ConjuntoNumerico();
c.add(2.5);
c.add(1.5);
System.out.println(\"Dados do conjunto...\");
System.out.println(\"media: \" + c.media());
double max = c.getMaximo();
System.out.println(\"maximo: \"+max);
}
}


Vejamos agora uma situação mais abrangente. Suponhamos que na verdade queremos criar um conjunto não apenas de números cujos valores são utilizados, mas sim uma conjunto de objetos quaisquer que possuam alguma característica de sirva de “medida” para que sejam comparados com outros objetos nas mesmas condições.

Poderíamos usar como medida o valor de número, a altura de uma pessoa, sua idade, a área de uma figura geométrica etc. O que importa é que tais objetos tenham um método que nos forneça uma “medida” que possa ser por nós utilizada.

Observe então que nesta situação, os objetos tem algo em comum, um método, e portanto nos vem logo em mente o princípio de herança, em que subclasses herdam métodos de superclasses.

No entanto, pelos exemplos citados, neste nosso caso é bastante claro que cada classe deve ter sua própria implementação do método que devolve sua medida. Um objeto “pessoa” retorna sua altura ou idade, um objeto “triângulo” retorna sua área etc.

Vemos assim que não haveria sentido em implementar esse método na superclasse, mas sim que cada classe tenha sua implementação.

Java nos oferece o conceito de “interface”. Trata-se de uma entidade semelhante a classes, mas cujos métodos não possuem implementação. Outras classes que herdam esses métodos os implementam de acordo com seu próprio contexto.

Vamos supor então que para nós os objetos a serem considerados em nosso conjunto mais geral devem ter então um método que devolva sua medida, todos são então “mensuráveis”. O que importa é que apenas eles sabem como devolver essa medida.

Esquematicamente poderíamos ter o seguinte:




Numa interface todos os métodos são ditos “abstratos”, têm nome, parâmetros e tipo de retorno, mas não têm implementação. Todos os métodos são automaticamente públicos, e uma interface não tem atributos, apenas constantes que são herdadas junto com os métodos.

Em nosso exemplo teríamos algo bem simples:

interface Mensuravel
{
double medida();
}

Classes poderiam então “implementar” a interface com a sintaxe dos exemplos abaixo:

class Pessoa implements Mensuravel
{
private String nome;
private double altura;
public Pessoa(String n, double a) {
nome = n;
altura = a;
}
public double medida() {
return altura;
}
}

class Retangulo implements Mensuravel
{
private double base , altura;
public Retangulo(double b, double a) {
base = b;
altura = a;
}
public double medida() {
return base*altura;
}
}

Enquanto uma classe pode estender uma única superclasse, uma mesma classe pode implementar mais de uma interface.

Observemos que nos exemplos as classes implementam o método descrito na interface, cada uma à sua maneira. Uma classe que implementa uma interface deve implementar todos os métodos da interface.

Nossa classe conjunto pode então ser adaptada para receber qualquer tipo de objeto de implemente a interface e assim possua um método que devolva uma medida para ser usada no conjunto.

Do mesmo modo que uma referência a uma superclasse pode indicar um objeto de qualquer de suas subclasses, uma referência a uma interface pode indicar qualquer objeto de classes que implementam a interface.


class ConjuntoDados
{
private int num;
private double soma;
private Mensuravel maximo;

public ConjuntoDados() {
num = 0;
soma = 0;
maximo = null;
}
public void add(Mensuravel x) {
soma += x.medida();
if (num==0 || maximo.medida() < x.medida())
{
maximo = x;
}
num++;
}
public double media() {
return (num>0?soma/num:0);
}
public Mensuravel getMaximo() {
return maximo;
}
}

E assim a classe do conjunto pode receber qualquer objeto que implemente a interface Mensuravel. Veja como fica o programa de teste:

class TesteConjunto
{
public static void main(String[] args)
{
ConjuntoDados c = new ConjuntoDados();
Pessoa p = new Pessoa(\"joao\", 1.80);
Retangulo r = new Retangulo(2.0, 1.5);
c.add(p);
c.add(r);
System.out.println(\"Dados do conjunto...\");
System.out.println(\"media: \" + c.media());
Mensuravel max = c.getMaximo();
System.out.println(\"maximo: \"+max.medida());
}
}


No esquema visto antes teríamos o seguinte agora:



Observemos no exemplo que dentro da classe ConjuntoDados a utilização do método medida() é feita de acordo com o objeto sendo adicionado. Se o objeto é uma pessoa, a implementação da classe Pessoa é utilizada, mas se o objeto é um retângulo, a implementação da classe Retangulo é utilizada. Este é o conceito de “polimorfismo” sendo aplicado. A forma correta do método é determinada pela classe do objeto sendo referenciado através da interface.