Ajuda com herança

Oi,

Estou com uma dúvida com relação a herança de classes.

Anexei meu projeto… entao essa é minha duvida.

Tenho uma classe chamada Bem.java, e 2 classes herdando esta classe(Edificio.java e Computador.java)

E passo a classe Bem por um interface(Depreciavel.java)

Na classe CadrastroBens.java, que é a void main, eu estancio uma variavel com a classe Bem:

Bem produto = null;

Então acesso os get e set por essa variavel produto.

Porem não consigo acessar o get e set da classe Computador ou Edifico.

Mas consigo calcular o valor da depreciacao baseado no valor de cada produto.

O que eu preciso fazer é o seguinte:

atualmente exibo uma janela(showOptionalDialog) em que o usuario escolhe se ele quer cadastrar um Edificio ou um Computador.

Ele preenche os valores CODIGO, DESCRICAO e VALOR pelo metodo set.

Ai começa o problema, pois se ele selecionar Edificio ele tambem deveria preencher a AREA(variavel que esta em Edificio.java).
E se selecionar computador ele deve preencher RAM(Computador.java)

Veja o modelo, creio que fiz tudo certo…

alguém sabe como posso resolver isso?

Obrigado


Quando você tem uma variável do tipo da superclasse como em

Bem produto = null;

e você quer acessar um método de uma subclasse através dessa variável, você deve definir os mesmo métodos na superclasse e subclasse. Por exemplo, você poderia criar um método setFeature(o método poderia ser abstract para forçar uma implementação na subclasse, mas lembre-se que a classe tendo um método abstract ela mesma deve ser abstract e, sendo assim, não pode ser instanciada) na superclasse(Bem) e sobrescrever esse método nas subclasses(Computador e Edifico). Então dentro deste método nas subclasses você chamaria o método específico de cada uma.

Na superclasse:

public abstract void setFeature(int value);

Nas subclasses:

//CLASSE EDIFICIO
public void setFeature(int value){
   setArea(value);
}
//CLASSE COMPUTADOR
public void setFeature(int value){
   setRam(value);
}

Bom, sua interface Bem só vai conhecer os métodos que são dela mesmo, e não de Computador ou Edifício.
Então, cria uma variavel Bem meuBem = null;
E de acordo com o selecionado, instancie um Computador ou Edificio;

Ex:

Bem meuBem = null;
if(opcaoSelecionada for um edificio)
    meuBem = new Edificio();
else if(opcaoSelecionada for um computador)
   meuBem = new Computador();

[quote=j0nny]Bom, sua interface Bem só vai conhecer os métodos que são dela mesmo, e não de Computador ou Edifício.
Então, cria uma variavel Bem meuBem = null;
E de acordo com o selecionado, instancie um Computador ou Edificio;

Ex:

Bem meuBem = null;
if(opcaoSelecionada for um edificio)
    meuBem = new Edificio();
else if(opcaoSelecionada for um computador)
   meuBem = new Computador();

[/quote]

Ola Jonny,

Isto na verdade já está feito… O Problema é que tenho a classe BEM como superclasse e Edificio e Computador como extends de BEM.
Estou tentando fazer como o Marcus falou.

Obrigado pela ajuda até agora :slight_smile:

Olá Marcus,

Segui a sua dica e parece que está funcionando… :slight_smile:

Porém estou com mais uma duvida.

Fiz um While para pegar os dados de RAM se computador ou de AREA se edificio:

while (true) { str = showInputDialog(null,"Informe o valor"); if (str == null) break; try { produto.setFeature(str); break; } catch(EDadoInvalido di) { showMessageDialog(null,di.getMessage(),"",ERROR_MESSAGE); } } if (str == null) break;

Só que na hora que vou pedir para o usuário, os 2 aparecem com o mesmo texto.
Tem como fazer aparece “Informe Area” se o usuario selecionar edificio… ou “Informe RaM” se o usuario selecionar computador.
Tentei fazer um if ali, mas aparentement não deu :frowning:

Alguma dica?

Já tentou utilizar o operador instanceof? Tem diversas formas de se fazer isso, uma delas seria com instanceof. Seria mais ou menos isso:

if(produto instanceof Edificio){
//Pede para informar a área
}else if(produto instanceof Computador){
//Pede para informar a RAM
}

Obrigado, funcionou :slight_smile:

Agora na hora de exibir os resultados, se coloco um método ToString na subclasse ele subscreve a da super classe.

Veja o que eu fiz:

Na super classe o meu método ToString está assim:

public String toString() { NumberFormat nf = NumberFormat.getCurrencyInstance(); return "Produto " + codigo + " (" + this.getClass().getName() + "): " + descricao + " - " + nf.format(valor); }

Porém na exibição eu também preciso informar a RAM se for um computador ou a Area se for um Edificio.
E eu preciso implementar o método ToString nas 2 subclasses. Veja o que tentei fazer:

EDIFICIO

public String toString() { return " - " + area + " metros²"; }

COMPUTADOR

public String toString() { return " - " + ram + " RAM"; }

Porém quando adicio esse método na subclasse, na hora de exibir uma mensagem creio que ele subrepõe o método ToString da superclasse, então não exibe nada na tela.

Sabe como posso usar um ToString nos 2 métodos da subclasse sem que isso afete a superclasse?

Obrigado,
Rodrigo

Tenta assim:

public String toString() {  
        return super.toString() + " - " + area + " metros²";  
}  

faz a mesma coisa nas duas classes(Edificio e Computador).

olá Marcus,

Funcionou perfeitamente… porém na hora de exibir a mensagem, ele está exibindo o valor 0 para ambos… o while que eu fiz para exibir foi esse:

[code]while (true) {
if(produto instanceof Edificio){
str = showInputDialog(null,“Informe a area”);
if (str == null) break;
}else if(produto instanceof Computador){
str = showInputDialog(null,“Informe a RAM”);
if (str == null) break;
}

			try {
				produto.setFeature(str);
				break;
			}
			catch(EDadoInvalido di) {
				showMessageDialog(null,di.getMessage(),"",ERROR_MESSAGE);
			}
		}
		if (str == null) break;[/code]

E este é o setFeature que estou usando

[code]public void setFeature(String value) {
setArea(Integer.parseInt(value));

} [/code]

De uma olhada na minha classe Edificio, é a mesma que a computador, só muda alguns nomes. Creio que esteja tudo certo

[code]public class Edificio extends Bem{
private int area;

public double calcularDepreciacao(char periodo){
	if(periodo == Bem.PERIODO_ANUAL)
		return super.getValor()*4/100;
	else
		if(periodo == Bem.PERIODO_MENSAL)
			return super.getValor()*4/100/12;
		else return 0;

}


public int getArea() {
	return area;
}


public void setArea(String p_area) throws EDadoInvalido {
	try {
		setArea(Integer.parseInt(p_area));
	}
	catch (NumberFormatException nfe) {
		throw new EDadoInvalido("A area deve ser um inteiro");
	}
}

private void setArea(int parseInt) {
	// TODO Auto-generated method stub

}


public void setFeature(String value) {  
	setArea(Integer.parseInt(value));

}  

public String toString() {    
	return super.toString() + " - " + area + " metros²";    
} 

}[/code]

Não sei porque, mas ele não está salvando o valor que digito na tela para o setFeature

Seu método setArea não tem implementação!

Olha este:

public void setArea(String p_area) throws EDadoInvalido { try { setArea(Integer.parseInt(p_area)); } catch (NumberFormatException nfe) { throw new EDadoInvalido("A area deve ser um inteiro"); } }

se eu deixar somente este método ele da um erro, dai pede para criar este método:

[code]private void setArea(int parseInt) {
// TODO Auto-generated method stub

}[/code]

Eu crio pelo ajuda do java… eu tenho que escrever algo dentro dele? sendo que o outro ja tem?

Então, nesse caso existe um problema com duas soluções.

Problema: Você está chamando um método que não faz nada. O método setArea(int). Sendo assim a variável não recebe um valor.

Solução 1 - Implementar o método setArea(int) para que ele faça alguma coisa.

Solução 2 - No método setFeature, ao invés de chamar um método setArea(int), chamar um método setArea(String). Mas para essa solução dar certo você não pode chamar um método setArea(int) dentro de setArea(String), e sim, deve fazer todo o trabalho dentro de setArea(String). Se você utilizar essa solução, pode excluir o método setArea(int).

Agora é apenas uma pequena confusão com as sobrecargas do método setArea.

[quote=marcusviniciusaso]Então, nesse caso existe um problema com duas soluções.

Problema: Você está chamando um método que não faz nada. O método setArea(int). Sendo assim a variável não recebe um valor.

Solução 1 - Implementar o método setArea(int) para que ele faça alguma coisa.

Solução 2 - No método setFeature, ao invés de chamar um método setArea(int), chamar um método setArea(String). Mas para essa solução dar certo você não pode chamar um método setArea(int) dentro de setArea(String), e sim, deve fazer todo o trabalho dentro de setArea(String). Se você utilizar essa solução, pode excluir o método setArea(int).

Agora é apenas uma pequena confusão com as sobrecargas do método setArea.[/quote]

Ola Marcus,

Obrigado, resolveu o problema =D