Downcasting

Bem estou com dúvidas em relação a downcasting em um programa que eu fiz usando poliformismo irei colocar o código para ficar mais fácil o entedimento
classe testa 1:

package com.testes.novos;

public class testa1 extends testa3
{
	private double totalRecebido;

	public testa1(String firstName, String lastName, String password, double salario, double comissao,double totalRcebido) 
	{
		super(firstName, lastName, password, salario, comissao);
		setTotalRecebido(totalRecebido);
	
	}
	
	public void setTotalRecebido(double totalRecebido)
	{
		this.totalRecebido=(super.getComissao()+super.getSalario());
	}
	
	public String toString()
	{
		return("Este objeto referencia a subclasse"+"\n"+"Nome:"+super.getFirstName()+"\n"+
				"Sobrenome: "+super.getlastName()+"\n"+"Senha: "+super.getPassword()+"\n"
			   +"Salário: "+super.getSalario()+"\n"+"Comissão "+super.getComissao()+"\n"+
				"O total recebido é "+totalRecebido);
	}
	

}

classe testa 2:


package com.testes.novos;

public class testa2 
{
	

	public static void main(String args[])
	{
		// atribui uma referencia de super classe a variavel de superclasse
		 testa3 chama = new testa3("Edson","Catugy","81345800786",500.00,54);
		 
//		 atribui uma referência de subclasse a variável de subclasse   
		 testa1 chama1= new testa1("Marcos","Lace","48118712647",450.0,1002,123);
		 
//		 invoca toString no objeto de superclasse utilizando a variável de superclasse
		 System.out.println(chama.toString());
		 
		 System.out.println();
//		 invoca toString no objeto de subclasse utilizando a variável de subclasse  
		 System.out.println(chama1.toString());
		 
		 testa3 chamaSub = chama1;
		 System.out.println();
		  // invoca toString no objeto de subclasse utilizando a variável de superclasse
		 System.out.println(chama1.toString());
		 
	}

}

classe testa 3:

package com.testes.novos;

public class testa3 
{
	private String firstName;
	private String lastName;
	private String password;
	private double salario;
	private double comisao;
	
	public testa3(String firstName,String lastName,String password,double salario,double comissao)
	{
		this.firstName=firstName;
		this.lastName=lastName;
		this.password=password;
		setSalario(salario);
		setComissao(comissao);
		
		
	}
	
	public void setSalario(double salario)
	{
		this.salario=((salario<0)?0:salario);
	}
	
	public void setComissao(double comissao)
	{
		this.comisao=((comissao<0)?0:comissao);
	}
	
	public String getFirstName()
	{
		return firstName;
	}
	
	public String getlastName()
	{
		return lastName;
	}
	
	public String getPassword()
	{
		return password;
	}
	
	public double getSalario()
	{
		return salario;
	}
	
	public double getComissao()
	{
		return comisao;
	}
	
	public String toString()
	{
		return("Este objeto referencia a super classe "+"\n"+"Nome: "+firstName+"\n"+
				"Sobrenome: "+lastName+"\n"+"Senha: "+password+"\n"+"Sálario: "+salario+
				"\n"+"Comissão: "+comisao);
	}

}

Bem nesta parte do programa eu fiz downcasting, “testa3 chamaSub = chama1;”, passando a referencia da subclasse para minha referência da superclasse, mais quando eu faço isso eu so posso usar métodos da minha subclasse? porque não posso usar tanto da superclasse quanto da subclasse.???

Superclasse você quis dizer né. O que vale é o tipo da variável, não o objeto que ela referencia.

Imagine a seguinte situação:

[code]public class Periferico {
public void ligar(){
System.out.println("Ligando…");
}
}

public class Impressora extends Periferico{
public void imprimir(){
System.out.println("Imprimindo…");
}
}

public class CaixaDeSom extends Periferico{
public void tocar(){
System.out.println("Tocando…");
}
}[/code]

Agora vamos usar as classes da forma certa:

Impressora imp = new Impressora(); imp.ligar(); imp.imprimir();
ok, liguei a impressora e mandei imprimir.

[code]Periferico p = new Impressora();
p.ligar();

p = new CaixaDeSom();
p.ligar();[/code]
Só posso ligar o periférico.

Agora do jeito que você queria:

Periferico p = new Impressora(); p.ligar(); p.imprimir();
Mas e se o objeto não fosse uma Impressora? Afinal você também pode colocar uma CaixaDeSom em “p”, aí você mandaria uma CaixaDeSom “imprimir”?

Periferico p = new CaixaDeSom(); p.ligar(); p.imprimir(); //bang

Os unicos membros que a variável garante que o objeto tem são os do seu próprio tipo e de superclasses desse tipo, ela não pode garantir que o objeto que ela referencia terá um método de uma classe que ela nem conhece.

Então, uma variável do tipo testa3 só pode garantir que o objeto que ela referencia tem os métodos de testa3, ela não pode garantir que o objeto terá os métodos declarados em testa1.

Seria como eu dizer a você, vai ali no meu computador e mande o periférico que está conectado a ele imprimir, e se você chegar lá e o periférico que está ligado no computador for um Scanner? Já se eu falar: vai ali no meu computador e ligue o periférico que está conectado a ele, aí sim, se for Scanner, Impressora, Câmera Digital, etc, todos eles tem um botão “ligar” que você vai poder apertar.

OK, Jair agora eu entendi

Porém,

public class Periferico {
	   public void ligar(){
	      System.out.println("Ligando Periferico...");
	   }
	}[/code]

[code]public class Impressora extends Periferico{
   public void imprimir(){
      System.out.println("Imprimindo...");
   }
}

public class CaixaDeSom extends Periferico{ public void tocar(){ System.out.println("Tocando..."); } public void ligar(){ System.out.println("Ligando Caixa de Som..."); } }

[code]
public class Main {

public static void main(String[] args) {

	Periferico p = new Periferico();
	
	p.ligar();			// Irá ligar o períferico....
	
	p = new CaixaDeSom();
	
	p.ligar();			// Irá ligar a caixa de som....
}

}[/code]

Você pode acessar apenas os métodos da subclasse que sobrescrevem os métodos da superclasse. Se você não quizer que esses métodos sejam sobrescritos pois ficaria redundante ou por qualquer outro motívo use final.

Até, JOhn. :cool: