Herança e polimorfismo! dá uma ajuda ai

discorpio: agradeço a sua ajuda. mas isso q vc falou eu ja sei e o que eu desejava não era atualizar a variavel “saldo” da classe mae “Conta”. Cada tipo de “Conta” tem sua variavel “saldo” pra uso próprio. bom mas vamos ao que interessa:
Como vcs podem ver ai em baixo temos 3 tipos de “Contas” e cada uma delas tem o metodo “double atualiza()” só que em todas elas a implementação desse metodo e diferente. Até ai tudo bem.
O problema surge quando na pagina 85 da apostila j11 Java OO ela pede pra usar a palavra “super” nos metodos herdados e reescritos (pra poupar trabalho de reescrever codigo - http://www.caelum.com.br/download/caelum-java-objetos-fj11.pdf) “double atualiza()” das classes filhas (no caso classe ContaCorrente.java e classe ContaPoupanca.java).
Ora o metodo “double atualiza()” herdado pelas classes filhas ContaCorrent.javae e ContaPoupanca.java da classe mae Conta.java já foi propositalmente reescrito pra que esse metodo herdado tivesse um comportamento diferente nessas classes filhas.
minha opinião é q eu nao devo ter entendido o enunciado corretamente ou q eu teria de ter feito um outro tipo de codigo para aplicar o que o enucidado pede.
para ser ainda mais claro veja sublinhado o codigo onde a apostila me pede pra usar “super” (nas classes ContaCorrente.javae e classe ContaPoupanca.java):
aqui abaixo a classe mae:

class Conta{
	protected double saldo;

	double getSaldo(){return this.saldo;}
	void deposita(double valor){this.saldo = this.saldo + valor;}
	void saca(double valor){this.saldo = this.saldo - valor;}
	double atualiza(double taxa){
		this.saldo = this.saldo + (this.saldo * taxa);
		return this.saldo;	
	}
}

aqui as duas classe filhas

class ContaCorrente extends Conta{
	double atualiza(double taxa){
		this.saldo = this.saldo + (this.saldo * (taxa * 2)); // usar super aqui? como? pra que?
		return this.saldo;
	}
	void deposita(double valor){this.saldo += (valor - 0.1);}
}
--------------------------------------------------------------------
class ContaPoupanca extends Conta{
	double atualiza(double taxa){
		this.saldo = this.saldo + (this.saldo * (taxa * 3));    // usar super aqui? como? pra que?
		return this.saldo;
	}
}

aqui um atualizador pra armazenar uns dados globais

class AtualizadorDeContas {
	private static double saldoTotal = 0;
	private static double selic;
	
	AtualizadorDeContas(double selic){
		this.selic = selic;
	}
	
	double getSaldoTotal(){return this.saldoTotal;}

	static void roda(Conta c){
		System.out.println("----------------------");
		System.out.println("Saldo incial desta conta: " + c.getSaldo());
		System.out.println("Saldo atualizado desta conta: " + c.atualiza(selic));
		saldoTotal += c.getSaldo();
	}
}

aqui o main

class TestaContas{
	public static void main(String[] args){
		Conta C1 = new Conta();
		ContaPoupanca CP1 = new ContaPoupanca();
		ContaCorrente CC1 = new ContaCorrente();
		
		C1.deposita(1000);
		CC1.deposita(1000);
		CP1.deposita(1000);
		
		AtualizadorDeContas atc = new AtualizadorDeContas(0.01);
		
		Banco BancoVista = new Banco();
		BancoVista.adiciona(C1);
		BancoVista.adiciona(CC1);
		BancoVista.adiciona(CP1);
		BancoVista.passaParaAtualizador();
		BancoVista.pegaTotalDeContas();
		System.out.println("Total de depositos: " + atc.getSaldoTotal());
	}
}

por ultimo a classe “Banco”

class Banco{
	Conta[] contas = new Conta[4];
	int totalContas;

	boolean adiciona(Conta c){
		for (int i=1; i<this.contas.length; i++){
			if (this.contas[i] == null){
				this.contas[i] = c;
				break;
			}
		}return true;
	}

	Conta pegaConta(Conta c){
		for(int i = 1; i < contas.length; i++){
			if (this.contas[i] == c){
				return this.contas[i];
			}
		}
	return this.contas[0];   //outra duvida minha é aqui pois tive de deixar a primeira posição do array sem gravar nada pra poder aqui dar um returnr duma conta (que eu nao queria mas se eu nao der da erro pq acursa falta de retorno). tb nao entendi isso. 
	}
	
	int pegaTotalDeContas(){
		for(int i = 1; i < contas.length; i++){
			if (this.contas[i] != null){
				this.totalContas++;
			}
		}
		return this.totalContas;
	}
	
	boolean passaParaAtualizador(){
		for(int i = 1; i < contas.length; i++){
			if (this.contas[i] != null){
				AtualizadorDeContas.roda(this.contas[i]);
			}		
		}
		return true;	
	}
}

Seu método tem o retorno do tipo void, sendo assim ele não retorna nada. Como vc está tentando dar um println, você teria mudar o retorno para o tipo double.

em vez de

 void atualiza(double taxa){ ... }

Terá que colocar

 double atualiza(double taxa)
{ 
  //implementa atualização
 return getSaldo();
}

Ou simplesmente tira o System.out.println(c.atualiza(selic));

 void roda(Conta c){  
        System.out.println(c.getSaldo());  
        System.out.println(c.atualiza(selic));  // pessoal aqui da um erro "void type not allowed here" já quebrei o cabeção e nao consegui descobrir!!!! :shock:   
        System.out.println(c.getSaldo());  
        saldoTotal += c.getSaldo();  

Deixando assim:

 void roda(Conta c){  
        System.out.println(c.getSaldo());  
        c.atualiza(selic);  // Simplesmente faz a atualização
        System.out.println(c.getSaldo());  
        saldoTotal += c.getSaldo();  

obrigado Erik
valeu mesmo!

pessoal o método “atualiza” é da classe mae Conta e foi reescrito nas classes ContaPoupança e ContaCorrente pois eu necessitava de um comportamento diferente desse metodo nas classes filhas.
Até ai tudo bem, mas agora o exercício me pede pra usar a palavra “super” nos metodos “atualiza” que foram reescritos. Será q isso nao está errado? pois se eu usar super eu to chamando o metodo da classe mae que tem uma funcionalidade diferente dos metodos reescritos “atualiza” na ContaPoupança e ContaCorrente!

[quote=rafaelczy]
aqui a classe mae:

class Conta{
	protected double saldo;

	double getSaldo(){return this.saldo;}
	void deposita(double valor){this.saldo = this.saldo + valor;}
	void saca(double valor){this.saldo = this.saldo - valor;}
	double atualiza(double taxa){this.saldo = this.saldo + (this.saldo * taxa); return this.saldo;}
}

abaixo as duas filhas

class ContaCorrente extends Conta{ double atualiza(double taxa){ this.saldo = this.saldo + (this.saldo * (taxa * 2)); return this.saldo; } void deposita(double valor){this.saldo += (valor - 0.1);} }

class ContaPoupanca extends Conta{ double atualiza(double taxa){ this.saldo = this.saldo + (this.saldo * (taxa * 3)); return this.saldo; } }

aqui a classe AtualizadorDeContas

[code]class AtualizadorDeContas {
private double saldoTotal = 0;
private double selic;

AtualizadorDeContas(double selic){
	this.selic = selic;
}

double getSaldoTotal(){return this.saldoTotal;}

void roda(Conta c){
	System.out.println(c.getSaldo()); 
	System.out.println(c.getSaldo());
	saldoTotal += c.getSaldo();
}

}[/code]

aqui o main

[code]class TestaContas{
public static void main(String[] args){
Conta C1 = new Conta();
ContaPoupanca CP1 = new ContaPoupanca();
ContaCorrente CC1 = new ContaCorrente();

	C1.deposita(1000);
	CC1.deposita(1000);
	CP1.deposita(1000);
	
	AtualizadorDeContas atc = new AtualizadorDeContas(0.01);
	atc.roda(C1);
	atc.roda(CC1);
	atc.roda(CP1);

	System.out.println("Total de depositos: " + atc.getSaldoTotal());
}

}[/code][/quote]

pessoal alguem pode me dar uma força no meu codigo ai em cima?
thanks :lol:

Boa noite a todos.

Não há nada de errado em usar o super nas classes que voce implementou, só que voce se esqueceu de um pequeno detalhe que a variável saldo que é do tipo double, terá valores diferentes para cada classe, dai a necessidade de se usar o super para atualizar o saldo da classe mãe (super classe) contas, para atualizar o saldo que se encontra em contas, e não nas classes herdadas.

O que voce precisa entender de Polimorfismo, é que na herança de classes, o que as classes herdam são apenas as suas variáveis tipadas e seus métodos, e não os valores das variáveis que tem uma referência diferente para cada classe. Portanto, se voce quisesse que o método atualiza tivesse comportantamento diferente para as classes herdadas porém mantivesse o valor saldo atualizado em apenas na classe mãe (contas) deverá usar super desta forma.

    class ContaPoupanca extends Conta {
          void atualiza(double taxa){  
                super.saldo += (super.saldo * (taxa * 3));  
          }  
    }

    class ContaCorrente extends Conta{
         void atualiza(double taxa){  
             super.saldo += (super.saldo * (taxa * 2));  
         }  
         void deposita(double valor){super.saldo += (valor - 0.1);}  
    }  

discorpio reeditei o post original com as novas considerações.
a todos que quiserem ajudar olhem o primeiro post la em cima pois acabei de editar e por tudo novo la
thanks :lol:

o problema da classe Banco resolvi:

class Banco{
	Conta[] contas = new Conta[4];
	int totalContas;
	Conta box;

	boolean adiciona(Conta c){
		for (int i=1; i<this.contas.length; i++){
			if (this.contas[i] == null){
				this.contas[i] = c;
				break;
			}
		}return true;
	}

	Conta pegaConta(Conta c){
		for(int i = 1; i < contas.length; i++){
			if (this.contas[i] == c){
				this.box = this.contas[i]; // tirei um return que tinha aqui devolvendo o "i" pois armazenei isso na var "box" (q é tipo Conta)
			}
		}
	return this.box; // e aqui p/ satisfazer a condição de retorno obrigatorio retornei aqui a var "box" q é uma "Conta" salva em algum posição do array hehehe
	}
	
	int pegaTotalDeContas(){
		for(int i = 1; i < contas.length; i++){
			if (this.contas[i] != null){
				this.totalContas++;
			}
		}
		return this.totalContas;
	}
	
	boolean passaParaAtualizador(){
		for(int i = 1; i < contas.length; i++){
			if (this.contas[i] != null){
				AtualizadorDeContas.roda(this.contas[i]);
			}		
		}
		return true;	
	}
}

permanece agora só a duvida exposta no primeiro post qto ao metodo “atualiza()” das classes filhas.
thank’s a lot

Boa noite a todos.

[quote=rafaelczy]permanece agora só a duvida exposta no primeiro post qto ao metodo “atualiza()” das classes filhas.
thank’s a lot[/quote]

Rafaelczy.

Esquece tudo que te falei no meu post anterior, até porque não sei de onde tirei esse “super.saldo”, que não faz referência a lugar nenhum, a não ser a variável da própria classe que a herda.

Corrigindo o meu erro, voce tem na classe Conta, o seguinte método:

   void atualiza(double taxa){
          this.saldo += (this.saldo * taxa);
   }

e na classe ContaCorrente sobrepõe (sobrescreve) o mesmo método assim:

     @Override
     void atualiza(double taxa){    
         this.saldo += (this.saldo * (taxa * 2));
     }

Repare que em ambos os métodos só há uma única diferença de implementação que é a taxa multiplicada por dois, porém o restante da expressão é a mesma, ou seja:

    ....
    // É a mesma em ambas as classes.
    ...
    this.saldo += (this.saldo * taxa);
    ...   

Logo voce não precisa reescrever essa mesma expressão em todas as classes que herdam de conta, bastando tão somente utilizar a sintaxe super desta maneira, na classe conta corrente que surtirá o mesmo efeito.

    /* Aqui voce só passará a taxa multiplica por dois
        que o método da super classe fará o resto com
        super. */
    void atualiza(double taxa){
          super.atualiza(taxa * 2);
    }

Quando voce reescreve métodos sobrepondo-os, e queremos apenas adicionar algo mais na implementação do método na super classe, não precisamos reescreve toda a implementação que está na super classe, bastando tão somente invocar a implementação com a sintaxe super e implementar o algo a mais logo a seguir. Esta é a finalidade do seu exercício em chamar o super.

Agora sim discorpio!
ajudou muito
valeu friend!
la vou eu para mais 4 horas de estudo na madrugada (estudo 8 hs por dia pra ver se arrumo um estagiozinho mais rapido)!
abração!

Olá Rafaelczy

[quote=rafaelczy]Agora sim discorpio!
ajudou muito
valeu friend!
la vou eu para mais 4 horas de estudo na madrugada (estudo 8 hs por dia pra ver se arrumo um estagiozinho mais rapido)!
abração![/quote]

Com certeza voce vai alcançar os seus objetivos desta maneira, só te oriento a fazer o que pretende de modo gradativo para não pirar depois, e nem tente alcançar os seus objetivos de modo rápido, pois todo aquele que percorre o caminho das pedras, mesmo que de forma lenta, conhecerá todo o caminho, e quando vier a percorrê-lo novamente saberá sair dele de modo mais fácil.

Deixo pra você um versiculo bíblico que é Eclesiastes capítulo 3, versículos de 1 a 10, leia e voce verá que tem tudo a ver com o que voce disse.

Um abraço.

discorpio: muito obrigado irmao!

Pessoal abaixo a classe mae Funcionario que ja consegui colocar como abstract
Depois dela vcs veem a filha Gerente se comunicando ok
E depois vcs veem a classe ControleDeBobificacoes, ai mora o problema pois nao estou conseguindo colocar como abstract. basta verem no meu main que to tendo que instancia ela.
Como faço pra me referir a ela no meu main sendo ela abstract ?

abaixo a classe mae Funcionario

public abstract class Funcionario {
	protected String nome;
	protected String cpf;
	protected double salario;
	protected double taxa = 0.01;
	
	public Funcionario(String nome, String cpf, double salario) {
		this.nome = nome;
		this.cpf = cpf;
		this.salario = salario;
	}

	double getBonificacao (){ return this.salario + this.salario * this.taxa;}
	
	String getDados(){
		return this.nome + this.cpf;
	} 
	
}

a filha Gerente

public class Gerente extends Funcionario{

	public Gerente(String nome, String cpf, double salario) {
		super(nome, cpf, salario);
		// TODO Auto-generated constructor stub
	}
	double getBonificacao(){
		return super.getBonificacao();
	}

}

a classe ControleDeBobificacoes

public class ControleDeBonificacoes {  //se eu seto "abstract" aqui nao sei como acessar la no main !!!!!
	private double totalDeBonificacoes;
	
	void registra (Funcionario funcionario){
		this.totalDeBonificacoes += funcionario.getBonificacao();
	}
	
	double getTotalDeBonificacoes(){
		return this.totalDeBonificacoes;
	}
}

o main

public class Principal {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Gerente F1 = new Gerente("Rafael Muinarczyki ", "60670975087", 1000.0);
		System.out.println(F1.getDados());
		System.out.println(F1.getBonificacao());
		
		Diretor D1 = new Diretor("Paulo Freitas ", "9876655443", 1000.0);
		System.out.println(D1.getDados());
		System.out.println(D1.getBonificacao());
		
		ControleDeBonificacoes CB1 = new ControleDeBonificacoes();
		CB1.registra(F1);
		CB1.registra(D1);
		System.out.println("Total de bonificacoes= " + CB1.getTotalDeBonificacoes());
		
	}

}

Pessoal !!! alguma ajuda ai sobre a minha impossibilidade de declarar a classe ControleDeBobificacoes no post ai em cima como “abstract” ? valeu!! :lol:

Uma classe abstrata não pode ser instanciada. Logo, se declarar a classe ControleDeBobificacoes como abstrata [size=18]NÃO poderá[/size] fazer isso no main:

ControleDeBonificacoes CB1 = new ControleDeBonificacoes(); 

certo gustavo mas nao tem um jeito de eu declarar ela como abstrata e mesmo assim usar ela no main (sem instanciar ela la) ?

Primeiro vc tem que saber o por que a classe tem que ser abstrada; sabendo disso talvez metado dos seus problemas sejam resolvidos.

P.S Apenas super classes podem ser abstratas.

flws

ok Fantomas -tinha me esquecido desse aspecto que so super classes podem ser abstratas
queria tornar a classe que me referi abastrata pra dar mais segurança ao codigo no sentido de ninguem poder criar uma referencia a um objeto dela (instanciar ela)!

Entendi…

Já que isto é um estudo digo o seguinte:

Neste caso que tal vc criar uma super classe que possuisse apenas o que vc quer que NÃO seja instanciado diretamente e depois uma classe filha que pudesse instanciada normalmente; como nas outras?

Por exemplo: Bonificacao (super classe abstrata), ControleDeBonificacao (classe filha de Bonificacao)