Dúvida

12 respostas
Anonner

Em um sistema de banco tenho dois tipos de conta, Conta1 e Conta2.
O que difere uma de outra é simples, Conta2 pode ter saldo negativo.
O programa está algo assim:
Interface Conta
Conta1 implements Conta
Conta2 extends Conta1 implements Conta
ListaConta (Que é uma ArrayList do tipo Conta1)
Conta2 tem os mesmos atributos de Conta1.
O problema é o seguinte, cadastro na arraylist tanto conta1 como conta2, porém eu vou efetuar um saque, eu estou conseguindo ter saldo negativo no tipo de conta Conta1(que não era para poder ter). E fiz os métodos tanto em Conta1 e Conta2, por polimorfismo ele não deveria saber que “método” usar?

12 Respostas

Rodrigo_Sasaki

Bom, vendo esse tópico, que não tem código nenhum pra exemplificar o que você está executando, a única coisa que posso responder é:

Sim! :slight_smile: por polimorfismo ele sabe qual o tipo do objeto real, e invoca o método do mesmo, independendo do tipo da variável.

drsmachado

Quando você vai pesquisar, vai até o google e digita “ajuda”? Ou procura por algum assunto específico como “problemas com polimorfismo”?
Portanto, ajude-se e nos ajude a te ajudar. Coloque títulos claros e seja objetivo (e não subjetivo) na descrição do problema).

Anonner

@Digao

O que eu esperava é que ele também fizesse isto por polimorfismo, porém não está fazendo. Erro meu?! Devo checar os métodos?!

@Machado

Só pensei em polimorfismo no final do que eu estava digitando, pois nem eu ao certo sei o erro. Me desculpe. Se tiver como mudar o nome do tópico, ajudará a comunidade.

ViniGodoy

E como vc garante que em Conta1 o saldo nunca fica negativo? Dispara exceção?

Outra coisa. Ao postar tópicos, por favor, dê um título descritivo. O título “Dúvida” não ajuda em nada quem lê a lista de tópicos.

Tome cuidado com outro detalhe. Se Conta2 é um Conta1, então você criou tipos de Conta1 que podem sim ser negativos.
É plenamente possível fazer:

Conta1 c1 = new Conta2(); c1.setSaldo(-100);

Lembre-se também que Conta2 respode “true” para a pergunta se ela é um “instanceof Conta1”.

Se conta2 não “é um” tipo de conta1, então, não use herança. Crie duas classes diferentes e herde a interface.
Se quiser evitar duplicação de código, crie um AbstractConta para ser pai das duas.

Anonner

@godoy

Exatamente isto.
Eu garantia que em Conta1 não teria saldo negativo no método de saque dela. Entende? O saldo nunca poderia ser menor que zero.
O que eu fiz foi colocar um atributo “tipoDeConta”, então logo no início dos dois métodos saque eu dou um if(tipoDeConta == 1) em um e no outro if(tipoDeConta == 0). Fiz isto e consegui o que eu queria, ou seja, só entra naquele especifico método se o atributo (tipoDeConta) for correspondente. Entende?

ViniGodoy

Pode postar suas classes Conta, por favor?

ViniGodoy

Aliás, isso está cheirando mal. Seu método de saque não deveria testar pelo tipo de conta. Afinal, ele já está na classe de conta certa.

Deveria ser algo como:

public class Conta1 { public void saque(int valor) { if (saldo - valor < 0) { throw new IllegalArgumentException("Não há dinheiro para realizar o saque.") saldo -= valor; } }

public class Conta2 extends Conta1 { public void saque(int valor) { saldo -= valor; } }

Sem qualquer tipo de teste.

Anonner
ViniGodoy:
Aliás, isso está cheirando mal. Seu método de saque não deveria testar pelo tipo de conta. Afinal, ele já está na classe de conta certa.

Deveria ser algo como:

public class Conta1 {
    public void saque(int valor) {
        if (saldo - valor < 0) {
            throw new IllegalArgumentException("Não  dinheiro para realizar o saque.")
        saldo -= valor;
    }
}
public class Conta2 extends Conta1 {
    public void saque(int valor) {
        saldo -= valor;
    }
}

Sem qualquer tipo de teste.

Opa, valeu pela força. Então, os meus métodos de saque são do tipo boolean, se há algum erro ele retorna false, irei postar os dois: De Conta1:
public Boolean saque(ListaDeConta lista, String numero, double valor, Data dt) throws ContaIneException{
		int pos = lista.pesquisaNumero(numero);
		if (lista.pesquisaNumero(numero) != -1){
			if(lista.get(pos).getTipoDeConta() == 0){


				if (lista.get(pos).getSaldo() - valor >= 0){
					lista.get(pos).setSaldo(lista.get(pos).getSaldo() - valor);
					return true;
				}
			}
		}
		return false;
	}
Conta2:
public Boolean saque(ListaDeConta lista, String numero, double valor, Data dt) throws ContaIneException{
		int pos = lista.pesquisaNumero(numero);
		if (lista.pesquisaNumero(numero) != -1){
			if(lista.get(pos).getTipoDeConta() == 1){


				if (lista.get(pos).getSaldo() >= 0 && lista.get(pos).getSaldo() - valor >= -1000){
					if (lista.get(pos).getSaldo() - valor < 0){
						lista.get(pos).setSaldo(lista.get(pos).getSaldo() - valor);
						classAux[i] = new ContaAux(dt, numero);
						size++;
						return true;
					}
					lista.get(pos).setSaldo(lista.get(pos).getSaldo() - valor);
					return true;
				}
			}
		}
		return false;
	}

Não repare nos pog. Então, eu tive que colocar o if(tipoDeConta == 1) em um e no outro if(tipoDeConta == 0) para funcionar do jeito que eu gostaria..

ViniGodoy

Esse seu método está estranho.
O método saque deveria sacar da própria conta, não de uma lista de contas.

Me parece que vc está com programação estruturada na cabeça (pensando em funções e dados, e não em classes).

Anonner

ViniGodoy:
Esse seu método está estranho.
O método saque deveria sacar da própria conta, não de uma lista de contas.

Me parece que vc está com programação estruturada na cabeça (pensando em funções e dados, e não em classes).

To começando a aprender agora. <img src="https://cdn.jsdelivr.net/gh/twitter/twemoji@14/assets/72x72/s.pngmiley.png?v=9" title=":smiley:" class="emoji" alt=":smiley:">

Então tipo, listaDeConta é uma arraylist de Conta1, por Conta2 dar extends em Conta1, eu posso colocar tanto Conta1 quanto Conta2 nessa Arraylist.

Ou seja por exemplo:

ListaDeConta lista = new ListaDeConta();

lista.add(new Conta1(os atributos de Conta1));

lista.saque(Número da conta, valor);

Conta1 não pode ter saldo negativo, porém se eu colocasse lá nos parâmetros o número da conta correspondente a uma Conta1 e um valor que deixasse o saldo negativo, ele entrava no método de saque correspondente ao Conta2(Que aceita ficar com saldo negativo), porém por polimorfismo ele deveria entrar no dele, mas isto não aconteceu. Por isso fiz aquela forçação de “tipoDeConta”, mas valeu pela ajuda, ainda tenho muito que aprender.

ViniGodoy

Um ArrayList vai aceitar os dois tipos de conta a partir do momento que você declara-lo assim:

List&lt;Conta&gt; contas = new ArrayList&lt;Conta&gt;();
Não era necessário criar uma nova classe, nem deriva-la de conta. Se você for criar uma classe para conter a lista, ela deve representar a entidade que guarda as contas, ou seja, o banco.
public class Banco {
   private List&lt;Conta&gt; contas = new ArrayList&lt;Conta&gt;();

   public void abrirConta(String numero, int tipo) {
       if (tipo == 0)
          contas.add(new Conta1(numero));
       else
         contas.add(new Conta2(numero));
   }

   public void retirarDeTodasAsContas(int valor) {
      for (Conta conta : contas) {
         conta.sacar(valor);
      }
   }
}

Se a classe Conta for como eu descrevi acima, o método retirarDeTodasAsContas irá disparar uma exceção quando a Conta apontada pela lista for uma Conta2. Isso por causa do polimorfismo do método sacar.
Como eu falei, não seria necessário haver um campo que testasse o tipo de conta. Se você está fazendo isso, é provavelmente um POG.

Anonner

Meu programa foi totalmente estruturado, nada de OO. Agora vou correr atrás do prejuízo. Valeu pela ajuda/aula Godoy. :smiley:

Criado 26 de junho de 2012
Ultima resposta 27 de jun. de 2012
Respostas 12
Participantes 4