Tem como eu fazer downcast em Java

3 respostas
rafael.espiritosanto

Olá pessoal!

Gostaria de saber se é possível fazer downcast em Java, ou seja, uma vez que tenha instanciado uma classe, ter a possibilidade de mais a frente informar que tal classe passe a se comportar como uma das sub-classes da classe original.

Pra ficar um pouco mais claro o problema.

Eis a classe ProcedimentoMetodologico
package br.ufrj.cos.ese.configuradorrs.entity.ontologia;

import java.io.Serializable;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.Name;

import br.ufrj.cos.ese.configuradorrs.entity.ontologia.procedimentoMetodologico.ApoioFerramental;
import br.ufrj.cos.ese.configuradorrs.entity.ontologia.procedimentoMetodologico.CodificacaoDados;
import br.ufrj.cos.ese.configuradorrs.entity.ontologia.procedimentoMetodologico.GerenciaDadosOmissos;
import br.ufrj.cos.ese.configuradorrs.entity.ontologia.procedimentoMetodologico.GerenciaUnidadeAnalise;
import br.ufrj.cos.ese.configuradorrs.entity.ontologia.procedimentoMetodologico.MetodoAnalise;
import br.ufrj.cos.ese.configuradorrs.entity.ontologia.procedimentoMetodologico.ProtocoloRevisaoSistematica;
import br.ufrj.cos.ese.configuradorrs.entity.ontologia.procedimentoMetodologico.RelatorioExecucaoRevisaoSistematica;



/**
 * @author Rafael
 * @version 1.0
 * @created 26-out-2010 12:07:48
 */
@Name("procedimentoMetodologico")
@AutoCreate
@Entity
public class ProcedimentoMetodologico implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -8355811334112074382L;
	private Long id;
	private String descricao;
	public RelatorioExecucaoRevisaoSistematica m_RelatorioExecucaoRevisaoSistematica;
	public ProtocoloRevisaoSistematica m_ProtocoloRevisaoSistematica;
	public GerenciaDadosOmissos m_GerenciaDadosOmissos;
	public ApoioFerramental m_ApoioFerramental;
	public MetodoAnalise m_MetodoAnalise;
	public CodificacaoDados m_CodificacaoDados;
	public GerenciaUnidadeAnalise m_GerenciaUnidadeAnalise;

	@Id @GeneratedValue
	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getDescricao() {
		return descricao;
	}

	public void setDescricao(String descricao) {
		this.descricao = descricao;
	}
	/*
	public RelatorioExecucaoRevisaoSistematica getM_RelatorioExecucaoRevisaoSistematica() {
		return m_RelatorioExecucaoRevisaoSistematica;
	}

	public void setM_RelatorioExecucaoRevisaoSistematica(
			RelatorioExecucaoRevisaoSistematica mRelatorioExecucaoRevisaoSistematica) {
		m_RelatorioExecucaoRevisaoSistematica = mRelatorioExecucaoRevisaoSistematica;
	}
	*/
	public ProtocoloRevisaoSistematica getM_ProtocoloRevisaoSistematica() {
		return m_ProtocoloRevisaoSistematica;
	}

	public void setM_ProtocoloRevisaoSistematica(
			ProtocoloRevisaoSistematica mProtocoloRevisaoSistematica) {
		m_ProtocoloRevisaoSistematica = mProtocoloRevisaoSistematica;
	}
	/*
	public GerenciaDadosOmissos getM_GerenciaDadosOmissos() {
		return m_GerenciaDadosOmissos;
	}

	public void setM_GerenciaDadosOmissos(GerenciaDadosOmissos mGerenciaDadosOmissos) {
		m_GerenciaDadosOmissos = mGerenciaDadosOmissos;
	}
	*/
	public ApoioFerramental getM_ApoioFerramental() {
		return m_ApoioFerramental;
	}

	public void setM_ApoioFerramental(ApoioFerramental mApoioFerramental) {
		m_ApoioFerramental = mApoioFerramental;
	}
	/*
	public MetodoAnalise getM_MetodoAnalise() {
		return m_MetodoAnalise;
	}

	public void setM_MetodoAnalise(MetodoAnalise mMetodoAnalise) {
		m_MetodoAnalise = mMetodoAnalise;
	}

	public CodificacaoDados getM_CodificacaoDados() {
		return m_CodificacaoDados;
	}

	public void setM_CodificacaoDados(CodificacaoDados mCodificacaoDados) {
		m_CodificacaoDados = mCodificacaoDados;
	}

	public GerenciaUnidadeAnalise getM_GerenciaUnidadeAnalise() {
		return m_GerenciaUnidadeAnalise;
	}

	public void setM_GerenciaUnidadeAnalise(
			GerenciaUnidadeAnalise mGerenciaUnidadeAnalise) {
		m_GerenciaUnidadeAnalise = mGerenciaUnidadeAnalise;
	}
	*/
	public ProcedimentoMetodologico(){

	}
}

Como vocês podem perceber, essa classe possui relacionamento com outras classes. Em minha aplicação, uma das primeiras coisas a serem feitas é instanciar um objeto do tipo ProtocoloRevisaoSistematica.
Sendo assim, para poder instanciar esse objeto eu devo instanciar antes um objeto do tipo ProcedimentoMetodologico.

Mais à frente, há um ponto onde é decidido que tipo de metodologia adotar, Para isso vou postar dois exemplos de 2 classes que herdam de ProcedimentoMetodologico
public class QuasiRevisaoSistematica extends ProcedimentoMetodologico {

	/**
	 * 
	 */
	private static final long serialVersionUID = -7701308951652636053L;

	public QuasiRevisaoSistematica(){

	}
}
e
public class MetaAnalise extends ProcedimentoMetodologico {

	/**
	 * 
	 */
	private static final long serialVersionUID = -2260206889790309648L;

	public MetaAnalise(){

	}
}

Sendo assim, com base na tomada de decisão do usuário, devo instanciar um objeto do tipo MetaAnalise ou QuasiRevisaoSistematica. No entanto, eu já tenho um objeto do tipo ProcedimentoMetodologico instanciado. Por isso, gostaria de saber se existe algum mecanismo de fazer o downcast, ou seja, dizer que o objeto do tipo ProcedimentoMetodologico agora vai assumir a identidade de MetaAnalise ou QuasiRevisaoSistematica

Se não for possível, qual seria a solução mais elegante para contornar este problema? (Contando com a restrição de que não é possível adiantar a parte da aplicação onde ocorre a tomada de decisão)

Abraço!

3 Respostas

G

Acho que ao invés de usar a herança vc poderia usar a composição. Isso deve resolver seu problema. “Mudar” o tipo de uma classe em tempo de execução não é possível. Ou vc instancia a classe no tipo “certo” ou com o tempo vc seta a a variavel co mum novo objeto do tipo mais apropriado.

Mas reitero que acho ser melhor usar a composição ao invés da herança entre a classe pai e as duas classes filhas.

rafael.espiritosanto

Pois é… o complicado é que tenho muitas restrições para mudar o modelo. Então fica difícil de transformar a herança em composição…
Acho que não tem jeito, vou ter instanciar um novo objeto e substituir o antigo pelo novo… :frowning:

Valeu pela ajuda!

rafael.espiritosanto

Olá!

Este post é um pouco off-topic mas o assunto surgiu a partir da dúvida original. Um conhecido comentou que na linguagem Eiffel esta operação é possível. No entanto fiquei na dúvida se a possibilidade de fazer um downcast é uma restrição do Java ou de “todas” as linguagens OO. Alguém conhece alguma linguagem aonde isto seja possível?

Valeu!

Criado 29 de outubro de 2010
Ultima resposta 30 de out. de 2010
Respostas 3
Participantes 2