Implementar uma interface (Poliformismo?)

Boa tarde Amigos,

Estou querendo entender definitivamente como usar Interfaces no java, a minha dúvida é a seguinte:

1- Tenho uma interface com a seguinte estrutura

[code]package br.com.testeInterfaces;

public interface Paciente {
public void setNome(String nome);
public void setIdade(Integer idade);
public String getNome();
public Integer getIdade();

}
[/code]

2- Tenho 2 classes que implementam a interface (Pessoa e Animal):
Além dos métodos em comum que obrigatoriamente terão de ser implementados eu adicionei o método getEstadoCivil na classe Pessoa E o método getRacaPedigree na classe Animal.

3- Criei um método de impressão que pega um objeto do tipo paciente, que pode ser (Paciente p = new Animal) ou (Paciente p = new Pessoa)
Neste método de impressão eu consigo imprimir tanto PESSOA quanto ANIMAL porém não consigo NO MESMO MÉTODO imprimir as PECULIARIDADES de cada objeto/classe = Estado Civil ou RacaPedigree :

[code] protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub

	Paciente pa = new Animal();
	pa.setNome("PitBul");
	pa.setIdade(10);
	
	Paciente pp = new Pessoa();
	pp.setNome("José Martins");
	pp.setIdade(45);
	
	PrintWriter out = response.getWriter();
	out.println(PrintIt(pa) + "<br>");
	
	out.println(PrintIt(pp));
	
}

public String PrintIt(Paciente p){
	
	String resultado = "------------- RELATÓRIO XX -------------<br>";
	resultado += "Nome: " + p.getNome() + "<br>";
	resultado += "Idade: " + p.getIdade() + "<br>";
	resultado += "------------------ FIM -----------------<br>";
	
	return resultado;
}[/code]

TEREI DE TER 2 MÉTODOS/classes diferentes? um que imprima além dos dados em comum como nome e idade os específicos estado civil e raca pedigree?

Sendo sincero, essa sua modelagem é falha. Não vejo a necessedidade de um internface.

vc pode criar uma classe Paciente e usar somente essa classe, definir um campo tipo, que indique se é uma pessoa ou animal.

Mas simples, e mais generico de uso.

Uma interface de gets e sets não é vantajosa não.

Cara

Quando você declara Paciente p = new Pessoa, a sua Referencia é para Paciente, mesmo a instancia sendo Pessoa. Mas enfim e daí? daí que você só poderá executar métodos que a sua referencia reconhece, ela não irá enxergar as particularidades das classes que a implementam ou seja umas instancia de Pessoa e Animal referenciadas por uma variável Paciente só poderam utilizar os membros descritos em Peciente.

Leia sobre conceito É-UM, nesse caso Pessoa e Animal É-UM Paciente.

[]'s

Emerson Rodrigo Costa

java

Se essa interface que você postou não for só para ilustrar sua dúvida, concordo plenamente com o Felagund, não é útil utilizar interface para getters e setters, use iterfaces para procedimentos mais expecíficos.

Emerson Rodrigo Costa

[quote=erodrigocosta]java

Se essa interface que você postou não for só para ilustrar sua dúvida, concordo plenamente com o Felagund, não é útil utilizar interface para getters e setters, use iterfaces para procedimentos mais expecíficos.

Emerson Rodrigo Costa[/quote]

Emerson, muito obrigado pela explicação do É-UM … deu pra entender.

Será que você tem algum exemplo mais prático do uso de interfaces? aonde várias classes implementam a mesma interface? (pra que eu possa entender) :wink: :wink: :wink: :wink:

Exatamente. Nem deveria. O método recebe Paciente e é apenas isso que ele pode trabalhar.
O método não sabe que existem outras classes com outros atributos. Nem deveria

Se vc quer imprimir as peculariedades a interface comum é inutil pois a interface só serve para o que é igual para os dois. Então, se é as peculariedades que quer, vc precisa de dois métodos.

[quote=java]
Será que você tem algum exemplo mais prático do uso de interfaces? aonde várias classes implementam a mesma interface? (pra que eu possa entender) :wink: :wink: :wink: :wink: [/quote]

Exemplo de classes de persistencia implementando uma interface.

[code]package br.com.agenciaviagens.dao;

import java.util.ArrayList;

public interface DAO {

public ArrayList<Object> carregarDados(Object obj, String orderBy) throws Exception;
/**
 * 
 * @param obj
 * @return primaryKey da inserção, zero em caso de falha
 * @throws Exception
 */
public int inserir(Object obj) throws Exception;
public boolean alterar(Object obj) throws Exception;
public boolean excluir(Object obj) throws Exception;

}
[/code]

package br.com.agenciaviagens.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;

import org.apache.log4j.Logger;

import br.com.agenciaviagens.obj.Cliente;

public class ClienteDAO implements DAO {
	
	private static Logger logger = Logger.getLogger(ClienteDAO.class);
	private Connection connection;
	
	public ClienteDAO(Connection conexao){
		connection = conexao;
	}

	@Override
	public boolean alterar(Object obj) throws Exception {
		Cliente cliente = (Cliente)obj;
		
		PreparedStatement pstmt = null;
		
		try{
			pstmt = connection.prepareStatement("update CLIENTE set NOME = ?, TELEFONE = ? where ID = ?");
			pstmt.setString(1, cliente.getNome());			
			pstmt.setString(2, cliente.getTelefone());
			pstmt.setInt(3, cliente.getId());
			
			pstmt.execute();
			pstmt.close();
			
		} catch (SQLException e) {			
			logger.error("Erro ao criar Statement(ClienteDAO - alterar)!");			
			e.printStackTrace();
			return false;
		}		
		
		return true;
	}

	@Override
	public ArrayList<Object> carregarDados(Object obj, String orderBy)
			throws Exception {
		Cliente cliente = (Cliente)obj;
		
		Statement stmt = null;
		ResultSet rs = null;
		ArrayList<Object> listaClientes = new ArrayList<Object>();
				
		try{
			stmt = connection.createStatement();
			
			//Monta a query de busca
			StringBuffer sql = new StringBuffer("select * from CLIENTE ");
						
			if(cliente.getId() != 0){
				if (sql.toString().contains("where")){
					sql.append(" and ID = '").append(cliente.getId() + "'");
				}else{
					sql.append(" where ID = '").append(cliente.getId() + "'");
				}
			}			
			
			if(cliente.getNome() != null){
				if (sql.toString().contains("where")){
					sql.append(" and NOME like '%").append(cliente.getNome() + "%'");
				}else{
					sql.append(" where NOME like '%").append(cliente.getNome() + "%'");
				}
			}			
			
			if(cliente.getTelefone() != null){
				if (sql.toString().contains("where")){
					sql.append(" and TELEFONE = '").append(cliente.getTelefone() + "'");
				}else{
					sql.append(" where TELEFONE = '").append(cliente.getTelefone() + "'");
				}
			}			
			
			if(orderBy != null && !orderBy.equals("")){
				sql.append(" order by ").append(orderBy);
			}
			
			//executa a busca
			rs = stmt.executeQuery(sql.toString());
			
			while(rs.next()){
				cliente = new Cliente();
				cliente.setId(rs.getInt("ID"));				
				cliente.setNome(rs.getString("NOME"));
				cliente.setTelefone(rs.getString("TELEFONE"));								
								
				listaClientes.add(cliente);
				
			}
			
			rs.close();
			stmt.close();
			
		} catch (SQLException e) {
			logger.error("Erro ao criar Statement(ClienteDAO - carregarDados)");			
			e.printStackTrace();
		}
		
		return listaClientes;
	}

	@Override
	public boolean excluir(Object obj) throws Exception {
		Cliente cliente = (Cliente)obj;		
		PreparedStatement pstmt = null;
		
		try{
			pstmt = connection.prepareStatement("delete from CLIENTE where ID = ?");			
			pstmt.setInt(1, cliente.getId());
			
			pstmt.execute();
			pstmt.close();
			
		} catch (SQLException e) {			
			logger.error("Erro ao criar Statement(ClienteDAO - excluir)!");			
			e.printStackTrace();
			return false;
		}		
		
		return true;
	}

	@Override
	public int inserir(Object obj) throws Exception {
		int primaryKey = 0;
		Cliente cliente = (Cliente)obj;		
		PreparedStatement pstmt = null;
		
		StringBuffer query = new StringBuffer("insert into CLIENTE (NOME, TELEFONE) ").
			append("VALUES (?, ?)");
		
		try{
			pstmt = connection.prepareStatement(query.toString());			
			pstmt.setString(1, cliente.getNome());			
			pstmt.setString(2, cliente.getTelefone());			
			
			pstmt.execute();
			
			String query2 = "SELECT LAST_INSERT_ID()";
			ResultSet rs = pstmt.executeQuery(query2);
			
			if(rs.next()){
				primaryKey = rs.getInt(1);
				logger.info("Cliente Inserido com ID: "+primaryKey);
			}
			
			rs.close();
			pstmt.close();
			
		} catch (SQLException e) {			
			logger.error("Erro ao criar Statement(ClienteDAO - inserir)!");			
			e.printStackTrace();
			return 0;
		}		
		
		return primaryKey;
	}

}
package br.com.agenciaviagens.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;

import org.apache.log4j.Logger;

import br.com.agenciaviagens.obj.Cidade;
import br.com.agenciaviagens.obj.Estado;

public class CidadeDAO implements DAO {
	
	private static Logger logger = Logger.getLogger(CidadeDAO.class);
	
	private Connection connection;
	
	public CidadeDAO(Connection conexao){
		connection = conexao;
	}

	@Override
	public boolean alterar(Object obj) throws Exception {
		Cidade cidade = (Cidade)obj;
		
		PreparedStatement pstmt = null;
		
		try{
			pstmt = connection.prepareStatement("update CIDADE set DESCRICAO = ?, ESTADO = ? where ID = ?");
			pstmt.setString(1, cidade.getDescricao());
			pstmt.setInt(2, cidade.getEstado().getId());
			pstmt.setInt(3, cidade.getId());
			
			pstmt.execute();
			pstmt.close();
			
		} catch (SQLException e) {			
			logger.error("Erro ao criar Statement(CidadeDAO - alterar)!");			
			e.printStackTrace();
			return false;
		}		
		
		return true;		
		
	}

	@Override
	public ArrayList<Object> carregarDados(Object obj, String orderBy)
			throws Exception {
		
		Cidade cidade = (Cidade)obj;
		
		Statement stmt = null;
		ResultSet rs = null;
		ArrayList<Object> listaCidades = new ArrayList<Object>();
		
		//Busca lista de Estados para inserir às cidades
		Estado estado = new Estado();		
		EstadoDAO estadoDAO = new EstadoDAO(connection);
		ArrayList<Object> listaEstado = estadoDAO.carregarDados(estado, "");
		
		try{
			stmt = connection.createStatement();
			
			//Monta a query de busca
			StringBuffer sql = new StringBuffer("select * from CIDADE ");
						
			if(cidade.getId() != 0){
				if (sql.toString().contains("where")){
					sql.append(" and ID = '").append(cidade.getId() + "'");
				}else{
					sql.append(" where ID = '").append(cidade.getId() + "'");
				}
			}
			if(cidade.getDescricao() != null){
				if (sql.toString().contains("where")){
					sql.append(" and DESCRICAO = '").append(cidade.getDescricao() + "'");
				}else{
					sql.append(" where DESCRICAO = '").append(cidade.getDescricao() + "'");
				}
			}
			
			if(orderBy != null && !orderBy.equals("")){
				sql.append(" order by ").append(orderBy);
			}
			
			//executa a busca
			rs = stmt.executeQuery(sql.toString());
			
			while(rs.next()){
				cidade = new Cidade();
				cidade.setId(rs.getInt("ID"));
				cidade.setDescricao(rs.getString("DESCRICAO"));				
				estado.setId(rs.getInt("ESTADO"));
				cidade.setEstado(selecionaEstadoDaLista(estado, listaEstado));				
				
				listaCidades.add(cidade);
				
			}
			
			rs.close();
			stmt.close();
			
		} catch (SQLException e) {
			logger.error("Erro ao criar Statement(CidadeDAO - carregarDados)");			
			e.printStackTrace();
		}		
				
		return listaCidades;		
	}
	
	
	public ArrayList<Object> carregarDadosPorEstado(Estado estado, String orderBy)
			throws Exception {
		ResultSet rs = null;
		PreparedStatement pstmt = null;
		ArrayList<Object> listaCidades = new ArrayList<Object>();
		
		//Busca lista de Estados para inserir às cidades		
		EstadoDAO estadoDAO = new EstadoDAO(connection);
		ArrayList<Object> listaEstado = estadoDAO.carregarDados(new Estado(), "");
		
		
		
		try{
			StringBuffer query = new StringBuffer("select * from CIDADE where ESTADO = ?");
			
			if(orderBy != null && !orderBy.equals(""))
				query.append(" order by ").append(orderBy);			
						
			pstmt = connection.prepareStatement(query.toString());
			pstmt.setInt(1, estado.getId());
			
			rs = pstmt.executeQuery();
			
			while(rs.next()){
				Cidade cidade = new Cidade();
				cidade.setId(rs.getInt("ID"));
				cidade.setDescricao(rs.getString("DESCRICAO"));
				cidade.setEstado(selecionaEstadoDaLista(estado, listaEstado));
				
				listaCidades.add(cidade);
			}
			
			
			pstmt.close();
			
		} catch (SQLException e) {			
			logger.error("Erro ao criar Statement(CidadeDAO - carregarDadosPorEstado)!");			
			e.printStackTrace();
			
		}		
				
		return listaCidades;
	}

	@Override
	public boolean excluir(Object obj) throws Exception {
		Cidade cidade = (Cidade)obj;
		PreparedStatement pstmt = null;
		
		try{
			pstmt = connection.prepareStatement("delete from CIDADE where ID = ?");
			pstmt.setInt(1, cidade.getId());
			
			pstmt.execute();
			pstmt.close();
			
		} catch (SQLException e) {			
			logger.error("Erro ao criar Statement(CidadeDAO - excluir)!");			
			e.printStackTrace();
			return false;
		}		
		
		return true;
	}
	
	public boolean excluirPorEstado(Object obj) throws Exception{
		Estado estado = (Estado)obj;
		
		PreparedStatement pstmt = null;
		
		try{
			pstmt = connection.prepareStatement("delete from CIDADE where ESTADO = ?");
			pstmt.setInt(1, estado.getId());
			
			pstmt.execute();
			pstmt.close();
			
		} catch (SQLException e) {			
			logger.error("Erro ao criar Statement(CidadeDAO - excluirPorEstado)!");			
			e.printStackTrace();
			return false;
		}		
		
		return true;
	}

	@Override
	public int inserir(Object obj) throws Exception {
		int primaryKey = 0;
		Cidade cidade = (Cidade)obj;
		PreparedStatement pstmt = null;
		
		try{
			pstmt = connection.prepareStatement("insert into CIDADE (DESCRICAO, ESTADO) values (?, ?)");
			pstmt.setString(1, cidade.getDescricao());
			pstmt.setInt(2, cidade.getEstado().getId());
			
			pstmt.execute();
			
			String query2 = "SELECT LAST_INSERT_ID()";
			ResultSet rs = pstmt.executeQuery(query2);
			
			if(rs.next()){
				primaryKey = rs.getInt(1);
				logger.info("Cidade Inserida com ID: "+primaryKey);
			}
			
			rs.close();
			pstmt.close();
			
		} catch (SQLException e) {			
			logger.error("Erro ao criar Statement(CidadeDAO - inserir)!");			
			e.printStackTrace();
			return 0;
		}		
		
		return primaryKey;
	}
	
	
	private Estado selecionaEstadoDaLista(Estado estado, ArrayList<Object> listaEstado){
		
		for (int i = 0; i < listaEstado.size(); i++) {
			if( ((Estado)listaEstado.get(i)).getId() == estado.getId() ){
				return (Estado)listaEstado.get(i);
			}
		}		
		
		return null;
	}

}

veja o codigo e espero q ajude…

[quote=sergiotaborda][quote=java]
Neste método de impressão eu consigo imprimir tanto PESSOA quanto ANIMAL porém não consigo NO MESMO MÉTODO imprimir as PECULIARIDADES de cada objeto/classe
[/quote]

Exatamente. Nem deveria. O método recebe Paciente e é apenas isso que ele pode trabalhar.
O método não sabe que existem outras classes com outros atributos. Nem deveria

Se vc quer imprimir as peculariedades a interface comum é inutil pois a interface só serve para o que é igual para os dois. Então, se é as peculariedades que quer, vc precisa de dois métodos.

[/quote]
Exatamente. O que você pode fazer é criar uma método na interface chamado getPeculiaridades e, em cada classe que implementa esta interface, escrever seu método específico. Mas não é possível acessar métodos específicos de uma classe que não esteja na interface, nesse caso.

Obrigado a todos que responderam, uma última pergunta.

Qual a vantagem de ser utilizar interfaces? se há apenas a declaração do método em comum e cada classe tem que IMPLEMENTAR os métodos da interface de forma diferente.

Na interface vejo apenas a declaração do método, normalmente 1 linha, e cada classe que implementa tem de fazer tudo… QUAL A VANTAGEM de se utilizar interfaces? Alguém usa?

public interface ImportadorArquivos{ public boolean importaArquivo(File arquivo); }

public class ImportaParaBanco implements ImportadorArquivos{

public boolean importaArquivo(File arquivo){
//importa os dados do arquivo e grava no banco de dados
}
}
public class ImportaParaTXT implements ImportadorArquivos{

public boolean importaArquivo(File arquivo){
//importa os dados do arquivo e grava em um arquivo TXT
}
}
public class Importa {

public void importaArquivoX(){
 //Obtem o arquivo X ...

ImportadorArquivos importador = getImportador();

importador.importaArquivo(arquivoX);


}

public ImportadorArquivos getImportador(){
 // retorna um tipo de importador
}


}

O que que o método getImportador retorna? um ImportaParaTXT ou um ImportaParaBanco ? Tanto faz. o método importaArquivoX não precisa saber qual é o tipo do importador. Ele só precisa saber que é um ImportadorArquivos, e que para importar o arquivo usa o método importaArquivo(). (frase mal escrita detected :roll: )

Cara!

A interface apenas determina um “contrato” em que as classes implementadoras devem seguir.
Para a interface, não importa como os métodos descritos por ela sejam implementados, o que importa é que sejam implementados.

Se usa uma interface para “padronizar”, essa é a palavra chave, pq aí você pode contar com um comportamento específico de todas as classes que a implementarem.

O exemplo que dei acima, as classes ClienteDAO e CidadeDAO implementando a interface DAO, é um exemplo de padronização de classes de persistência (acesso a banco de dados), todas as classes que implementem DAO obrigatoriamente terão de ter os N comportamentos, e ao se empregar o polimorfismo por exemplo: DAO dao = new CidadeDAO(); eu poderia ter certeza que poderia invocar esses comportamentos de DAO no objeto CidadeDAO.

Então para finalizar lembre-se sempre, o uso da interface é uma espécie de herança onde a classe pai, nesse caso uma interface, não se preocupa em implementar os métodos, ele delega a implementação às classes filhas.

Espero ter ajudado.

Espero que este exemplo te ajude a entender.

Se você observar o framework de Collections, presente na API do Java, por exemplo, verá a interface Collection.

Esta interface define um contrato que todas as classes que a implementam (ou que implementam suas subinterfaces) devem seguir.

E daí? Daí que você tem certeza que qualquer classe que segue este contrato, terá os métodos add, remove, clear, contains, size, toArray, dentre outros.

Imagine que você tem um trecho assim:

private Collection<MinhaClasse> minhaColecao;

E a instancia assim:

minhaColecao = new ArrayList<MinhaClasse>();
// depois chamo esses métodos
metodo1(minhaColecao);
metodo2(minhaColecao);
metoto3(minhaColecao);

Seguem os métodos

private void metodo1(Collection<MinhaClasse> c) {
// faz algo
}
private void metodo2(Collection<MinhaClasse> c) {
// faz outra coisa
}
private void metodo3(Collection<MinhaClasse> c) {
// faz mais alguma coisa
}

Ótimo. Tudo funciona perfeitamente. Mas depois você percebe que precisa de uma lista ordenada (o ArrayList não é) e que não permita elementos repetidos (mais uma característica que o ArrayList não tem). Você descobre que precisará usar um TreeSet (que também implementa Collection).

E agora? O que fazer? Simples: mude a palavra ArrayList, na instanciação, para TreeSet. Resolvido.

Porque foi tão simples? Pois ao declarar o tipo da variável e usar na assinatura dos métodos a interface Collection, você sabe que algum tipo de coleção será usado. Não importa qual. Importa que é uma coleção e implementará os métodos definidos na interface.

Agora imagine se você tivesse tipado todas as variáveis com ArrayList (o mais específico) ao invés de Collection. Caso você precisasse alterar o tipo para TreeSet você teria que mudar o tipo da variável, a instanciação, a assinatura de todos os métodos e talvez seus corpos, caso usasse algum método específico de ArrayList.

[size=18]RodrigoCosta, MarcoBiscaro e Mario[/size] muito obrigado pelas informações!

Entendi o sentido de se utilizar interfaces.

Valeu pessoal!

Esse GUJ só tem fera mesmo!
:lol: :lol: :lol: :lol: :lol: :lol: :lol: :lol: :lol: